{"record":{"id":"7510a71112085875","repo":"iflytek/astron-agent","slug":"credential-file-is-unavailable","errorCode":null,"errorMessage":"credential file is unavailable","messagePattern":"credential file is unavailable","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/config/credential_file_other.go","lineNumber":15,"sourceCode":"//go:build !linux && !darwin\n\npackage config\n\nimport (\n\t\"errors\"\n\t\"os\"\n)\n\n// openCredentialFileNoFollow is a portability fallback for platforms without\n// O_NOFOLLOW. Supported production images use the Unix implementation above.\nfunc openCredentialFileNoFollow(fileName string) (*os.File, error) {\n\tpathInfo, err := os.Lstat(fileName)\n\tif err != nil {\n\t\treturn nil, errors.New(\"credential file is unavailable\")\n\t}\n\tif pathInfo.Mode()&os.ModeSymlink != 0 || !pathInfo.Mode().IsRegular() {\n\t\treturn nil, errors.New(\n\t\t\t\"credential file must be a regular non-symbolic-link file\",\n\t\t)\n\t}\n\tfile, err := os.Open(fileName)\n\tif err != nil {\n\t\treturn nil, errors.New(\"credential file is unavailable\")\n\t}\n\topenedInfo, err := file.Stat()\n\tif err != nil || !openedInfo.Mode().IsRegular() || !os.SameFile(pathInfo, openedInfo) {\n\t\t_ = file.Close()\n\t\treturn nil, errors.New(\"credential file changed while being opened\")\n\t}\n\treturn file, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/config/credential_file_other.go#L1-L33","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the *_FILE environment variable points to an existing, correctly mounted path","Check that the secret volume mounted successfully in the container (kubectl describe pod / docker inspect)","Fix the path typo or create/restore the credential file, then restart the service"],"exampleFix":"// before\nTENANT_KEY_FILE=/secrets/tenant.key   # file not mounted\n// after\n# mount the secret at /secrets and verify: ls -l /secrets/tenant.key\nTENANT_KEY_FILE=/secrets/tenant.key","handlingStrategy":"validation","validationCode":"if info, err := os.Lstat(path); err != nil {\n    return fmt.Errorf(\"credential file %s missing/unavailable: %w\", path, err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := config.LoadTenantBootstrapCredentials(ctx); err != nil {\n    if strings.Contains(err.Error(), \"unavailable\") {\n        logger.Fatal(\"credential file path not mounted; check *_FILE env and volume mounts\")\n    }\n    return err\n}","preventionTips":["Verify *_FILE paths exist in the container entrypoint before startup","Ensure secret volumes mount successfully (check pod events)","Keep credential paths consistent between manifests and code"],"tags":["filesystem","credentials","file-not-found","tenant"],"backgroundTag":"file-not-found","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}