t8y2/dbx · error

Oracle tnsnames.ora was not found in TNS_ADMIN directory: %s

Error message

Oracle tnsnames.ora was not found in TNS_ADMIN directory: %s

What it means

Once TNS_ADMIN is confirmed as an accessible directory, the driver stats <dir>/tnsnames.ora and requires it to exist and not be a directory. If the file is missing (or is itself a directory), resolution of any alias cannot proceed and this error is returned naming the TNS_ADMIN directory.

Source

Thrown at agents/drivers/oracle-go/tns.go:97

	descriptor, ok := aliases[strings.ToUpper(config.Alias)]
	if !ok {
		return "", fmt.Errorf("Oracle TNS alias %q was not found in %s", config.Alias, tnsNamesPath)
	}
	return descriptor, nil
}

func oracleTNSNamesPath(tnsAdmin string) (string, error) {
	path := filepath.Clean(strings.TrimSpace(tnsAdmin))
	info, err := os.Stat(path)
	if err != nil {
		return "", fmt.Errorf("Oracle TNS_ADMIN directory is not accessible: %s", path)
	}
	if !info.IsDir() {
		return "", fmt.Errorf("Oracle TNS_ADMIN must be a directory containing tnsnames.ora: %s", path)
	}
	tnsNamesPath := filepath.Join(path, "tnsnames.ora")
	if info, err := os.Stat(tnsNamesPath); err != nil || info.IsDir() {
		return "", fmt.Errorf("Oracle tnsnames.ora was not found in TNS_ADMIN directory: %s", path)
	}
	return tnsNamesPath, nil
}

func readOracleTNSAliases(path string, visited map[string]bool, depth int) (map[string]string, error) {
	if depth > 8 {
		return nil, fmt.Errorf("Oracle TNS include depth exceeds 8 files")
	}
	absolutePath, err := filepath.Abs(path)
	if err != nil {
		return nil, fmt.Errorf("Failed to resolve Oracle TNS file path: %w", err)
	}
	if visited[absolutePath] {
		return map[string]string{}, nil
	}
	visited[absolutePath] = true

	file, err := os.Open(absolutePath)

View on GitHub (pinned to c0390bff16)

Solutions

  1. Copy or create tnsnames.ora inside the TNS_ADMIN directory (exact lowercase spelling on case-sensitive filesystems).
  2. Verify it is a regular file: ls -l $TNS_ADMIN/tnsnames.ora.
  3. Fix deployment/backup tooling so the file is included in the mounted volume or image.
  4. If aliases live in another file, point TNS_ADMIN at the directory that actually contains tnsnames.ora.

Example fix

// before
# /opt/oracle/network/admin contains only ldap.ora
// after
cp tnsnames.ora /opt/oracle/network/admin/tnsnames.ora
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(filepath.Join(tnsAdmin, "tnsnames.ora"))
if err != nil || info.IsDir() {
	return fmt.Errorf("tnsnames.ora missing in %s", tnsAdmin)
}

Try / catch

if strings.Contains(err.Error(), "tnsnames.ora was not found") {
	return fmt.Errorf("deploy tnsnames.ora into the TNS_ADMIN directory: %w", err)
}

Prevention

When it happens

Trigger: resolveOracleTNSAlias -> oracleTNSNamesPath finds a valid TNS_ADMIN directory but tnsnames.ora is absent from it, or a directory named tnsnames.ora exists in its place.

Common situations: New TNS_ADMIN directory created but the tnsnames.ora never copied in; deployment pipelines mounting the directory without the file; file named tnsnames.ora.bak or TNSNAMES.ora on a case-sensitive filesystem; a directory accidentally named tnsnames.ora.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/7e02cd7b08c6cd94. Report an issue: GitHub.