Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORA-29278: SMTP transient error: Service not available when running UTL_MAIL

Tags:

oracle

plsql

We are planning to install the UTL_MAIL Package and we're currently testing the installation steps in our Development Environment. After sucessfully installing the UTL_MAIL Package Scripts and creating the sufficient PUBLIC Synonyms and Grants, we are getting the error ORA-29278 when running the test Anonymous Block below:

BEGIN 

    UTL_MAIL.SEND(sender     => '[email protected]'
                , recipients => '[email protected]'
                , subject    => 'Testmail'
                , message    => 'Hello');

END;

Full Details of the error Message:

ORA-29278: SMTP transient error: 421 4.3.2 Service not available
ORA-06512: at "SYS.UTL_MAIL", line 662
ORA-06512: at "SYS.UTL_MAIL", line 679
ORA-06512: at line 3
29278. 00000 -  "SMTP transient error: %s"
*Cause:    A SMTP transient error occurred.
*Action:   Correct the error and retry the SMTP operation.    

As per research from related links (Send Email Using PLSQL), i may need to setup the proper access control list (ACL) for this to work. However, upon executing the script below, i'm still getting the same error.

DECLARE
   -- ACL name to be used for email access reuse the same value for all 
   -- future calls
   l_acl         VARCHAR2 (30) := 'utl_smtp.xml';
   -- Oracle user to be given permission to send email
   l_principal   VARCHAR2 (30) := 'APPS';
   -- Name of email server
   g_mailhost    VARCHAR2 (60) := 'smtprelay.xxxxx.com';
   l_cnt         INTEGER;

   PROCEDURE validate_smtp_server
   AS
      l_value       v$parameter.VALUE%TYPE;
      l_parameter   v$parameter.name%TYPE := 'smtp_out_server';
   BEGIN

      SELECT VALUE
        INTO l_value
        FROM v$parameter
       WHERE name = l_parameter;

      IF l_value IS NULL
      THEN
         raise_application_error (
            -20001
          ,    'Oracle parameter '
            || l_parameter
            || ' has not been set'
            || UTL_TCP.crlf
            || 'it s/b smtprelay.alorica.com'
         );
      END IF;

      DBMS_OUTPUT.put_line ('parameter ' || l_parameter || ' value is ' ||     l_value);

   END validate_smtp_server;

   PROCEDURE create_if_needed (p_acl IN VARCHAR2)
   AS
      l_cnt   INTEGER;
   BEGIN

      SELECT COUNT (*) c
        INTO l_cnt
        FROM dba_network_acls a
       WHERE SUBSTR (acl, INSTR (acl, '/', -1) + 1) = p_acl;

      IF l_cnt = 0
      THEN
         DBMS_OUTPUT.put_line ('creating acl ' || p_acl);
         DBMS_NETWORK_ACL_ADMIN.create_acl (
            acl         => p_acl
          , description => 'Allow use of utl_smtp'
          , principal   => l_principal
          , is_grant    => TRUE
          , privilege   => 'connect'
         );

         DBMS_NETWORK_ACL_ADMIN.assign_acl (acl => p_acl, HOST => g_mailhost);
         COMMIT;
      ELSE
         DBMS_OUTPUT.put_line (p_acl || ' acl already exists');
      END IF;

   END create_if_needed;

   PROCEDURE add_if_needed (
      p_principal   IN VARCHAR2
    , p_acl         IN VARCHAR2
   )
   AS
      l_cnt   INTEGER;
   BEGIN

      SELECT COUNT (*) c
        INTO l_cnt
        FROM dba_network_acl_privileges
       WHERE SUBSTR (acl, INSTR (acl, '/', -1) + 1) = p_acl
         AND principal = p_principal;

      IF l_cnt = 0
      THEN
         DBMS_NETWORK_ACL_ADMIN.add_privilege (
            acl       => 'utl_smtp.xml'
          , principal => p_principal
          , is_grant  => TRUE
          , privilege => 'connect'
         );
         COMMIT;
         DBMS_OUTPUT.put_line ('access to ' || p_acl || ' added for ' ||     p_principal);
      ELSE
         DBMS_OUTPUT.put_line (p_principal || ' already has access to ' || p_acl);
      END IF;

   END add_if_needed;
BEGIN

   EXECUTE IMMEDIATE 'grant execute on utl_mail to ' || l_principal;

   create_if_needed (p_acl => l_acl);
   add_if_needed (p_principal => l_principal, p_acl => l_acl);
   DBMS_OUTPUT.put_line ('Verification SQL:');
   DBMS_OUTPUT.put_line ('    SELECT * FROM dba_network_acls;');
   DBMS_OUTPUT.put_line ('    SELECT * FROM dba_network_acl_privileges;');
   COMMIT;
   validate_smtp_server;
END;

What other steps can i take or what other instructions do i need to provide to the DBAs for this?

Oracle Database Version:

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
"CORE   11.2.0.4.0  Production"
TNS for Solaris: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

Thank you very much.

like image 745
Migs Isip Avatar asked Dec 29 '16 09:12

Migs Isip


1 Answers

I was able to resolve this by contacting our System Administrator and asking for the details of the Mail Server. Turns out, if we'll only be sending the email internally, we are advised to use a different server mail.xxx.xxx.xxxx since its not going to be blocked by the firewall. On the other hand, if we'll be sending email externally, another server is involved smtprelay.xxxxx.com and this involves an extra step of Whitelisting the External Servers to be sent to.

As i checked in V$PARAMETER, we were using the smtprelay.xxxxx.com server and decided to try the other server mail.xxx.xxx.xxxx.

I issued the Alter command as below:

alter system set smtp_out_server = 'mail.xxx.xxx.xxxx';

and ran the anonymous block and was able to recieve the email successfully.

BEGIN 

    UTL_MAIL.SEND(sender     => '[email protected]'
                , recipients => '[email protected]'
                , subject    => 'Testmail'
                , message    => 'Hello');

END;
like image 52
Migs Isip Avatar answered Oct 26 '22 00:10

Migs Isip