{"record":{"id":"874f1bb1d1027b2c","repo":"iflytek/astron-agent","slug":"credential-file-is-unavailable-unix","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_unix.go","lineNumber":28,"sourceCode":")\n\n// openCredentialFileNoFollow resolves and opens the credential in one kernel\n// operation. O_NOFOLLOW prevents a path swap to a symbolic link between a\n// separate path inspection and open; O_NONBLOCK prevents a hostile FIFO from\n// blocking startup before the descriptor type is checked with fstat.\nfunc openCredentialFileNoFollow(fileName string) (*os.File, error) {\n\tfd, err := unix.Open(\n\t\tfileName,\n\t\tunix.O_RDONLY|unix.O_CLOEXEC|unix.O_NOFOLLOW|unix.O_NONBLOCK,\n\t\t0,\n\t)\n\tif err != nil {\n\t\tif errors.Is(err, unix.ELOOP) {\n\t\t\treturn nil, errors.New(\n\t\t\t\t\"credential file must be a regular non-symbolic-link file\",\n\t\t\t)\n\t\t}\n\t\treturn nil, errors.New(\"credential file is unavailable\")\n\t}\n\treturn os.NewFile(uintptr(fd), fileName), nil\n}\n","sourceCodeStart":10,"sourceCodeEnd":32,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/config/credential_file_unix.go#L10-L32","documentation":"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.","triggerScenarios":"unix.Open(fileName, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK, 0) fails with any error other than ELOOP.","commonSituations":"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.","solutions":["Confirm the file exists at the exact path and the service user can open it (sudo -u <svcuser> cat <path>)","Fix the secret mount/permissions (chown/chmod or correct the volume mount config)","Check fd limits (ulimit -n) and systemd LimitNOFILE if errors appear under load","Inspect audit logs (SELinux denials / apparmor) if permissions look correct"],"exampleFix":"# before\n# docker-compose: no secret mounted\n# after\ndocker-compose:\n  secrets:\n    - tenant_credential\n  # file then exists at /run/secrets/tenant_credential as a regular file","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(path); err != nil {\n    return fmt.Errorf(\"credential file %q not accessible: %w\", path, err)\n}","typeGuard":null,"tryCatchPattern":"f, err := openCredentialFileNoFollow(path)\nif err != nil {\n    if serr := os.Stat(path); serr != nil {\n        return fmt.Errorf(\"credential file missing at %q: %w\", path, serr)\n    }\n    return fmt.Errorf(\"credential file at %q cannot be opened (permissions/fd limit?): %w\", path, err)\n}","preventionTips":["Pre-flight check existence and permissions of the credential path at container start","Ensure the secret volume mount is present in every environment's deployment config","Run the service as a user that owns or can read the credential file","Raise LimitNOFILE/ulimit -n for services opening many files"],"tags":["go","unix","file-open","permissions"],"backgroundTag":"file-open-failed","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"}