iflytek/astron-agent · error

credential file is unavailable

Error message

credential file is unavailable

What it means

openCredentialFileNoFollow is the portability fallback used on platforms lacking O_NOFOLLOW. It Lstat's the credential path first and fails with 'credential file is unavailable' when the path itself cannot be stated — i.e. the file does not exist or is otherwise inaccessible to lstat. Production Unix images use the O_NOFOLLOW implementation instead.

Solutions

  1. Confirm the *_FILE environment variable points to an existing, correctly mounted path
  2. Check that the secret volume mounted successfully in the container (kubectl describe pod / docker inspect)
  3. Fix the path typo or create/restore the credential file, then restart the service

Example fix

// before
TENANT_KEY_FILE=/secrets/tenant.key   # file not mounted
// after
# mount the secret at /secrets and verify: ls -l /secrets/tenant.key
TENANT_KEY_FILE=/secrets/tenant.key
Defensive patterns

Strategy: validation

Validate before calling

if info, err := os.Lstat(path); err != nil {
    return fmt.Errorf("credential file %s missing/unavailable: %w", path, err)
}

Try / catch

if _, err := config.LoadTenantBootstrapCredentials(ctx); err != nil {
    if strings.Contains(err.Error(), "unavailable") {
        logger.Fatal("credential file path not mounted; check *_FILE env and volume mounts")
    }
    return err
}

Prevention

When it happens

Trigger: credentialFromEnvironmentOrFile resolves a *_FILE env var, openCredentialFileNoFollow calls os.Lstat(fileName), and the path is missing (ENOENT), a broken symlink target, or lstat is denied by permissions.

Common situations: The *_FILE env var points at a path never mounted into the container, the secret volume failed to mount, a typo in the file path, or the credential file was deleted before startup.

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 iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/7510a71112085875. Report an issue: GitHub.

Appendix: source

Thrown at core/tenant/config/credential_file_other.go:15

//go:build !linux && !darwin

package config

import (
	"errors"
	"os"
)

// openCredentialFileNoFollow is a portability fallback for platforms without
// O_NOFOLLOW. Supported production images use the Unix implementation above.
func openCredentialFileNoFollow(fileName string) (*os.File, error) {
	pathInfo, err := os.Lstat(fileName)
	if err != nil {
		return nil, errors.New("credential file is unavailable")
	}
	if pathInfo.Mode()&os.ModeSymlink != 0 || !pathInfo.Mode().IsRegular() {
		return nil, errors.New(
			"credential file must be a regular non-symbolic-link file",
		)
	}
	file, err := os.Open(fileName)
	if err != nil {
		return nil, errors.New("credential file is unavailable")
	}
	openedInfo, err := file.Stat()
	if err != nil || !openedInfo.Mode().IsRegular() || !os.SameFile(pathInfo, openedInfo) {
		_ = file.Close()
		return nil, errors.New("credential file changed while being opened")
	}
	return file, nil
}

View on GitHub (pinned to 5e758547a8)