iflytek/astron-agent · error

credential file is unavailable

Error message

credential file is unavailable

What it means

The unix open of the credential file failed with an error other than ELOOP (which has its own symlink-specific message). This generic 'unavailable' error covers ENOENT (missing file), EACCES (permission denied), ENFILE/EMFILE (fd exhaustion), ENOTDIR (path component not a directory), etc. The OS-level reason is intentionally masked.

Solutions

  1. Confirm the file exists at the exact path and the service user can open it (sudo -u <svcuser> cat <path>)
  2. Fix the secret mount/permissions (chown/chmod or correct the volume mount config)
  3. Check fd limits (ulimit -n) and systemd LimitNOFILE if errors appear under load
  4. Inspect audit logs (SELinux denials / apparmor) if permissions look correct

Example fix

# before
# docker-compose: no secret mounted
# after
docker-compose:
  secrets:
    - tenant_credential
  # file then exists at /run/secrets/tenant_credential as a regular file
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(path); err != nil {
    return fmt.Errorf("credential file %q not accessible: %w", path, err)
}

Try / catch

f, err := openCredentialFileNoFollow(path)
if err != nil {
    if serr := os.Stat(path); serr != nil {
        return fmt.Errorf("credential file missing at %q: %w", path, serr)
    }
    return fmt.Errorf("credential file at %q cannot be opened (permissions/fd limit?): %w", path, err)
}

Prevention

When it happens

Trigger: unix.Open(fileName, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK, 0) fails with any error other than ELOOP.

Common situations: Secret not mounted in the container (missing volume mount); service user lacks read permission on the file or a parent directory; too many open files under load; path contains a file where a directory is expected; SELinux/AppArmor blocking access.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/874f1bb1d1027b2c. Report an issue: GitHub.

Appendix: source

Thrown at core/tenant/config/credential_file_unix.go:28

)

// openCredentialFileNoFollow resolves and opens the credential in one kernel
// operation. O_NOFOLLOW prevents a path swap to a symbolic link between a
// separate path inspection and open; O_NONBLOCK prevents a hostile FIFO from
// blocking startup before the descriptor type is checked with fstat.
func openCredentialFileNoFollow(fileName string) (*os.File, error) {
	fd, err := unix.Open(
		fileName,
		unix.O_RDONLY|unix.O_CLOEXEC|unix.O_NOFOLLOW|unix.O_NONBLOCK,
		0,
	)
	if err != nil {
		if errors.Is(err, unix.ELOOP) {
			return nil, errors.New(
				"credential file must be a regular non-symbolic-link file",
			)
		}
		return nil, errors.New("credential file is unavailable")
	}
	return os.NewFile(uintptr(fd), fileName), nil
}

View on GitHub (pinned to 5e758547a8)