iflytek/astron-agent · error
load
Error message
load %s: %w
What it means
When the direct credential env var is unset, credentialFromEnvironmentOrFile falls back to reading the file named by the *_FILE env var. 'load %s: %w' wraps a readCredentialFile failure — the file could not be opened, is not a regular non-symlink file, exceeds 4096 bytes, or cannot be read — with the variable name for context.
Solutions
- Check the wrapped cause: 'no such file or directory' → fix the path; 'permission denied' → fix file mode/owner.
- Ensure the path points to a regular file, not a symlink or directory (readCredentialFile explicitly rejects symlinks).
- Keep the secret file ≤4096 bytes with a single-line value (it is trimmed of surrounding whitespace).
- Verify the volume mount in the pod spec projects the secret key as a plain file at that exact path.
Example fix
// before
TENANT_KEY_FILE=/run/secrets/tenant/key.txt # file does not exist
// after (k8s volume)
volumes:
- name: tenant-bootstrap
secret: { secretName: tenant-bootstrap, items: [{ key: tenant-key, path: key }] }
# TENANT_KEY_FILE=/run/secrets/tenant-bootstrap/key Defensive patterns
Strategy: validation
Validate before calling
if p := os.Getenv("TENANT_KEY_FILE"); p != "" {
if info, err := os.Stat(p); err != nil || !info.Mode().IsRegular() {
return fmt.Errorf("TENANT_KEY_FILE %s is not a readable regular file", p)
}
} Try / catch
value, err := readCredentialFile(name)
if err != nil {
return "", fmt.Errorf("load %s: %w", fileEnvironment, err)
} Prevention
- Mount secrets as regular projected files, not symlinked tmpfs dirs.
- Set restrictive but sufficient file modes (0400) and correct ownership.
- Keep secret files small (single line, well under 4096 bytes).
When it happens
Trigger: TENANT_KEY_FILE or TENANT_SECRET_FILE is set but readCredentialFile fails: path does not exist, permission denied, path is a symlink or directory, file larger than maxCredentialFileBytes (4096), or an I/O error during read.
Common situations: Secret mounted as a symlinked directory (older k8s symlink mounts) rejected by the no-follow open; wrong path or typo in _FILE var; file mounted with wrong permissions/owner; the mounted secret accidentally contains a large multi-line bundle.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- credential file changed while being opened
- database password is required
- load tenant bootstrap credentials failed
- mysql password is empty
- must contain 32-50 valid UTF-8 characters
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/a94d72e75b07871f.
Report an issue: GitHub.
Appendix: source
Thrown at core/tenant/config/bootstrap_credentials.go:98
}
return nil
}
func credentialFromEnvironmentOrFile(valueEnvironment, fileEnvironment string) (string, error) {
if value := strings.TrimSpace(os.Getenv(valueEnvironment)); value != "" {
if err := validateCredential(valueEnvironment, value); err != nil {
return "", err
}
return value, nil
}
fileName := strings.TrimSpace(os.Getenv(fileEnvironment))
if fileName == "" {
return "", fmt.Errorf("%s or %s is required", valueEnvironment, fileEnvironment)
}
value, err := readCredentialFile(fileName)
if err != nil {
return "", fmt.Errorf("load %s: %w", fileEnvironment, err)
}
if err := validateCredential(valueEnvironment, value); err != nil {
return "", err
}
return value, nil
}
func readCredentialFile(fileName string) (string, error) {
file, err := openCredentialFileNoFollow(fileName)
if err != nil {
return "", err
}
defer func() {
_ = file.Close()
}()
openedInfo, err := file.Stat()
if err != nil {View on GitHub (pinned to 5e758547a8)