Ed Stevens, DBA

February 26, 2011

ora-12154/tns-03505

Filed under: TNS — Ed Stevens @ 8:03 pm

Continuing the discussion of “why can’t I connect to my database?”, I’d like to focus on one particular error – ora-12154. For this discussion and demonstration we will use Oracle’s sqlplus command processor as our client, but the principles apply to any client program that uses sqlnet to connect to the database.

There are actually several mechanisms for connecting to an Oracle database, but by far the most common is via the Oracle Call Interface (OCI), passing the connect request via Oracle’s Transparent Network Substrate (TNS), commonly referred to as “sqlnet”.

Hardly a day goes by that someone doesn’t post a problem on OTN, reporting they are getting an ora-12154 trying to connect to their database. And invariably they are sent on a wild goose chase, checking everything that can go wrong anywhere along the network stack. And yet, ora-12154 means one thing, and one thing only: The client side of sqlnet could not find the specified connect identifier. Period. And the official description of the error, returned by the Oracle utility “oerr” spells it out:

[oracle@vmlnx01 ~]$ oerr ora 12154
12154, 00000, "TNS:could not resolve the connect identifier specified"
// *Cause:  A connection to a database or other service was requested using
// a connect identifier, and the connect identifier specified could not
// be resolved into a connect descriptor using one of the naming methods
// configured. For example, if the type of connect identifier used was a
// net service name then the net service name could not be found in a
// naming method repository, or the repository could not be
// located or reached.

Or more succinctly: “A connection … was requested using a connect identifier (which) could not be resolved into a connect descriptor.” So what is the connect identifier? Let’s take the classic, textbook example of a simple client connection request:

c:> sqlplus scott/tiger@orcl

By the rules Oracle uses to parse the command line, the “@” symbol is used to mark the beginning of the connect identifier. So in this example, the connect identifier is “orcl”, and an ora-12154 means an entry for “orcl” could not be resolved to a “connect descriptor” – the IP address, port number, and service name necessary to properly route the request across the network to the Oracle listener. There are several methods available to make this name resolution, but by far the most common is the use of “local naming”  – the tnsnames.ora file. This file serves no other purpose, so you should have it fixed firmly in your mind that it is used only by the client process. The only reason this file exists on the database server is because the server can also run client processes.

With this preliminary information out of the way, let’s dig in and see how many ways we can create (and conversely, fix) an ora-12154. Let’s first look at a good configuration, then we’ll start taking it apart. My database is running on an Oracle Enterprise Linux server, while my client is running on my laptop, under Windows XP-Pro. My tnsnames.ora looks like this:

# tnsnames.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\net
work\admin\tnsnames.ora
# Generated by Oracle configuration tools.
#===========================
mytestdb =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmlnx01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vlnxora1)
    )
  )

Make a connection to the database, just to show that everything is in order.

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:14:38 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Right out of the textbook! So what could go wrong, to generate an ora-12154?

Wrong naming method

The first thing sqlnet has to do is determine what naming method is being used – exactly how it is to resolve the connect identifier to an IP address, port, and service name. To do this, it looks in the file ‘sqlnet.ora’ (on the client machine, of course!) for the parameter NAMES.DIRECTORY_PATH. If we intend to use local naming, we must set this parameter appropriately:

NAMES.DIRECTORY_PATH= (TNSNAMES)

(Note: the string ‘TNSNAMES’ as a value for this parameter is not the name of the file.  It is the name of the method to be used for name resolution.  The name of the file used for this method is always tnsnames.ora.)

Let’s set it to some other value (albeit a valid one) . . .

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (LDAP)

. . . and observe the behavior

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:27:46 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

In this example, we told sqlnet to use LDAP naming services to resolve the connect identifier, but LDAP is not available in my test environment, thus it was not able to resolve “mytestdb”.  Lesson: If you want to use local naming, you must specify such in the SQLNET.AUTHENTICATION_SERVICES parameter in the client’s sqlnet.ora file. Let’s fix the problem, then move on:

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES)

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:52:33 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Can’t locate tnsames.ora

The entire subject of locating tnsnames.ora was covered in “Help! I can’t connect to my database (part duex)“. For now, I will create the simplest means of not being able to locate the file – I’ll rename it to something else . . .

C:\>cd C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>ren tnsnames.ora tnsnames.sav

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>dir tnsnames.ora
 Volume in drive C has no label.
 Volume Serial Number is 04C2-AD70

 Directory of C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN

File Not Found

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>

. . . and observe the result:

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:57:14 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

Of course, we fix it by providing a (valid) tnsnames.ora file:

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>ren tnsnames.sav tnsnames.ora

C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 15:58:37 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

Can’t find connect descriptor in tnsnames.ora

We’ve told sqlnet to use tnsnames, and we’ve made sure sqlnet can find tnsnames.ora. But what if the connect identifier we provide cannot be found in the tnsnames.ora? And more importantly, what can cause it to not be found?

Of course, the simplest reason would be that we just gave it the wrong string. In our example file (shown above), we had a single entry, with the connect identifier of ‘mytestdb’. If we provide a different connect identifier it will, of course fail – again with ora-12154:

C:\>sqlplus scott/tiger@fubar

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:05:48 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

But there is another factor that comes into play at this point. There is an optional parameter that can be set in sqlnet.ora that we have not yet discussed. Before looking in tnsnames.ora, sqlnet will check to see if the parameter NAMES.DEFAULT_DOMAIN has been set. If it has, it’s value will be appended to the connect descriptor supplied by the user – before searching tnsames.ora for the result. Let’s add that parameter to our existing sqlnet.ora . . .

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\sqlnet.ora
# sqlnet.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\netwo
rk\admin\sqlnet.ora

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES)
NAMES.DEFAULT_DOMAIN=acme.com

. . . and observe the result

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:13:42 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

There are two ways to fix this error. Obviously, we can revert back to our previous configuration by removing the NAMES.DEFAULT_DOMAIN parameter from sqlnet.ora. The other would be to add the domain name to the entry in tnsnames.ora.

C:\>type C:\oracle\product\10.2.0\client_1\NETWORK\ADMIN\tnsnames.ora
# tnsnames.ora Network Configuration File: C:\oracle\product\10.2.0\client_1\net
work\admin\tnsnames.ora
#===========================
mytestdb.acme.com =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = vmlnx01)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = vlnxora1)
    )
  )

C:\>sqlplus scott/tiger@mytestdb

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:30:57 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL>

tns-03505

That pretty well covers every means of creating an ora-12154 when using local naming. What about the tns-03505 error? Actually, tns-3505 is exactly the same error as ora-12154, with all the same causes and resolutions. The only difference I’ve been able to discover is that tns-03505 is produced when using the ‘tnsping’ utility. Why Oracle chose to code tnsping this way I don’t know, and I’ve been unable to find definitive documentation on this difference but my own testing bears it out.

Using sqlplus . . .

C:\>sqlplus scott/tiger@fubar

SQL*Plus: Release 10.2.0.4.0 - Production on Sat Feb 26 16:44:33 2011

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

ERROR:
ora-12154: TNS:could not resolve the connect identifier specified

Enter user-name:

And using tnsping . . .

C:\>tnsping fubar

TNS Ping Utility for 32-bit Windows: Version 10.2.0.4.0 - Production on 26-FEB-2
011 16:44:42

Copyright (c) 1997,  2007, Oracle.  All rights reserved.

Used parameter files:
C:\oracle\product\10.2.0\client_1\network\admin\sqlnet.ora

tns-03505: Failed to resolve name

C:\>

(Thanks to Sybrand Bakker for pointing out this distinction).

I will discuss ‘tnsping’, it’s use, what it does and does not do, in another post.

This’n'that

There is one often overlooked ‘gotcha’ in all this. Remember that when sqlnet is parsing out the connect string, it uses the ‘@’ sign as a meta-character to mark the beginning of the connect descriptor. So if we have this:

c:>sqlplus scott/tiger@orcl

everything is just fine. But suppose there is an ‘@’ sign someplace unexpected. What happens if someone constructs a complex password that includes it?

c:> sqlplus scott/P@ssW0rd@orcl

In this case, sqlnet will take the ‘P’ as the password, and take ‘ssW0rd@orcl’ as the connect descriptor.  By now, you can guess the result.

Conclusion

In this post I have attempted to demonstrate every possible cause of an ora-12154 error, as relates to use of tnsnames.ora, for address resolution of a connect descriptor. There is one overriding factor here that should be obvious from the very description of the error, regardless of the naming method used: ora-12154 is a client side problem. It has absolutely nothing to do with anything on the server. It has nothing to do with the listener; it has nothing to do with the database. If you are faced with a ora-12154, you can monkey around with your database and/or listener “until the cows come home” and you will not solve your problem.

Stay tuned for more discussion of sqlnet connection  problems.

About these ads

17 Comments »

  1. Great post. You’ve given a great understanding of the error rather than the myriad of possible solutions found over the net.
    I ran into most of those issues, and one more – having two Oracle clients installed on one machine, which somehow messed up (and didn’t report) which tnsnames.ora file was used.

    Comment by Seth — July 22, 2011 @ 9:14 am | Reply

  2. Seth – Glad it helped. I’m a bit puzzled by your comment that you were unable to report which tnsames.ora was being used. This should have been shown with tnsping. Of course, that would only reflect the environment of the command line processor where you executed tnsping – not necessarily the environment of some app.

    Also, the various options were discussed in “Help! I can’t connect to my database (part duex)”. Did you check that out?

    Comment by Ed Stevens — July 22, 2011 @ 1:12 pm | Reply

  3. Excellent Resolution! This is simply superb.
    Thank you Ed.

    Comment by Krish Sridhara — July 28, 2011 @ 10:26 am | Reply

  4. Thank you !

    Comment by Rick Willemain — March 15, 2012 @ 5:51 pm | Reply

  5. Thank you for wonderfull article, but i would like add some more reference.

    Do not make the password contain oracle reserve word for example G@ssPr4t.

    Oracle will check this @ character as reserve word which defined as connection string.

    After i change the password, then i can login successfully. :-)

    Comment by Ajinomoto — June 6, 2012 @ 11:47 pm | Reply

    • Yep. Exactly what I pointed out under “This’n'That”

      Just to ‘pick a nit’, I wouldn’t consider that a ‘reserved word’. Simply a character that Oracle uses as a delimiting tag.

      Comment by Ed Stevens — June 7, 2012 @ 5:40 pm | Reply

  6. Thank You for your wonderful article……!!!!

    Comment by Shibin George — July 21, 2012 @ 12:43 am | Reply

  7. Think I’ve got one you overlooked: The “(x86)” in the directory path C:\Program Files (x86)\… exposes a networking bug in Oracle, causing a 12154 error because (I guess) it can’t locate the tnsnames.ora file. See http://social.msdn.microsoft.com/Forums/en-NZ/sqlintegrationservices/thread/ab662d63-6385-4f73-b27f-d526048f601f

    Comment by androidicus — July 25, 2012 @ 3:40 pm | Reply

    • I haven’t tested specifically for that, but I’ve heard lots of reports of Oracle not playing well with Windows directory names with embedded spaces. I’ve seen reports of that in dealing with installations try to place ORACLE_HOME in a Windows directory with spaces. So I’d guess it has more to do with the spaces than the (x86). Maybe I’ll do some testing with that in the next couple of days.

      Comment by Ed Stevens — July 25, 2012 @ 8:03 pm | Reply

  8. One more note:
    if you are using TNS_ADMIN with GI installation (RAC or Oracle Restart environment)
    don’t foget to set srvctl setenv db -d YouDB -t TNS_ADMIN=path_to_tnsnames.ora_folder
    for all DBs that start via srvctl start db.
    to check: srvctl getenv db -d YouDB

    Comment by Prosvet — August 20, 2012 @ 1:41 am | Reply

  9. The best posting about this problem. Spent many hours on how to solve it until I finally found this website! Thank you!

    Comment by Ann — October 2, 2012 @ 9:21 pm | Reply

  10. Superb article…it helped me a lot…. thank you so muchhhhhhhh

    Comment by SNigdha — October 31, 2012 @ 12:32 am | Reply

  11. when i try to connect using:
    $ORACLE_SID=mydb
    $sqlplus sys/sys as sysdba@mydb
    It connect successfully.
    But when i use:
    $sqlplus sys/sys@mydb
    ORA-12514: TNS:listener does not currently know of service requested in connect
    descriptor.
    Listener is runnig, but says ‘not processing any service’
    I have checked sqlnet.ora and tnsname.ora, both files are perfect.
    Please help

    Comment by arvi — December 7, 2012 @ 8:28 am | Reply

    • Offhand, I can’t think of anything. Something like this would be better discussed on the OTN forum (https://forums.oracle.com/forums/forum.jspa?forumID=61). I’d suggest you post your question there. I’m pretty active there, and you can get participation from several other people as well. Never hurts to have several sets of eyes looking at a problem. When you post there, please be sure to state your version of Oracle, to 4 decimals, your OS, and copy and paste an entire command line session demonstrating the problem. Much better to show actual inputs and responses as opposed to your own description/interpretation of them.

      Comment by Ed Stevens — December 7, 2012 @ 5:17 pm | Reply

  12. Great article explaining in details the way to find the solution. Helped me immensely. Thhank you

    Comment by RS — January 8, 2013 @ 10:10 am | Reply

  13. […] TROUBLESHOOTING GUIDE: ORA-12154 & TNS-12154 TNS:could not resolve service name [ID 114085.1] ora-12154/tns-03505 | Ed Stevens, DBA __________________ You can lead some folks to knowledge, but you can not make them think. The […]

    Pingback by Error while connect database by usnig EXP.exe utility - dBforums — May 13, 2013 @ 8:32 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Rubric. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 66 other followers

%d bloggers like this: