{"record":{"id":"6542913f4e3932b5","repo":"ipfs/kubo","slug":"failed-to-raise-ulimit-to-ipfs-fd-max-d-set-to","errorCode":null,"errorMessage":"failed to raise ulimit to IPFS_FD_MAX (%d): set to %d","messagePattern":"failed to raise ulimit to IPFS_FD_MAX \\((.+?)\\): set to (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cmd/ipfs/util/ulimit.go","lineNumber":93,"sourceCode":"\tcase syscall.EPERM:\n\t\t// lower limit if necessary.\n\t\tif targetLimit > hard {\n\t\t\ttargetLimit = hard\n\t\t}\n\n\t\t// the process does not have permission so we should only\n\t\t// set the soft value\n\t\terr = setLimit(targetLimit, hard)\n\t\tif err != nil {\n\t\t\terr = fmt.Errorf(\"error setting ulimit without hard limit: %w\", err)\n\t\t\tbreak\n\t\t}\n\t\tnewLimit = targetLimit\n\n\t\t// Warn on lowered limit.\n\n\t\tif newLimit < userLimit {\n\t\t\terr = fmt.Errorf(\n\t\t\t\t\"failed to raise ulimit to IPFS_FD_MAX (%d): set to %d\",\n\t\t\t\tuserLimit,\n\t\t\t\tnewLimit,\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\n\t\tif userLimit == 0 && newLimit < minFds {\n\t\t\terr = fmt.Errorf(\n\t\t\t\t\"failed to raise ulimit to minimum %d: set to %d\",\n\t\t\t\tminFds,\n\t\t\t\tnewLimit,\n\t\t\t)\n\t\t\tbreak\n\t\t}\n\tdefault:\n\t\terr = fmt.Errorf(\"error setting: ulimit: %w\", err)\n\t}","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/cmd/ipfs/util/ulimit.go#L75-L111","documentation":"After an EPERM fallback that raises only the soft limit, ManageFdLimit checks whether the achieved limit met the user's explicit IPFS_FD_MAX. If the hard limit capped it lower, this error reports the requested versus achieved value. It signals the user-requested file-descriptor count could not be honored, not a hard failure of the setrlimit call itself.","triggerScenarios":"ManageFdLimit() with IPFS_FD_MAX set to N, the initial setLimit(N, N) hits EPERM, the soft-only fallback succeeds but targetLimit was clamped to the hard limit, and newLimit < N.","commonSituations":"Operator sets IPFS_FD_MAX=65536 in an environment where the hard limit is only 4096 (default systemd or shell limits); production daemons expecting high connection counts on hosts with restrictive login limits.","solutions":["Raise the hard limit for the daemon user (`ulimit -Hn`, /etc/security/limits.conf, or systemd LimitNOFILE=hard) so it is >= IPFS_FD_MAX.","Run the daemon as root or with CAP_SYS_RESOURCE capability, which allows raising limits up to the kernel max (fs.nr_open).","Lower IPFS_FD_MAX to match the existing hard limit so the request and outcome agree."],"exampleFix":"// before (systemd unit)\n# no LimitNOFILE, IPFS_FD_MAX=65536\n// after (systemd unit)\n[Service]\nLimitNOFILE=65536\nEnvironment=IPFS_FD_MAX=65536","handlingStrategy":"validation","validationCode":"hard, err := getHardNoFileLimit() // via Getrlimit(RLIMIT_NOFILE)\nif err != nil { return err }\nif v := os.Getenv(\"IPFS_FD_MAX\"); v != \"\" {\n    want, _ := strconv.ParseUint(v, 10, 64)\n    if want > hard {\n        log.Warnf(\"IPFS_FD_MAX=%d exceeds hard limit %d; raise LimitNOFILE first\", want, hard)\n    }\n}","typeGuard":null,"tryCatchPattern":"changed, newLimit, err := util.ManageFdLimit()\nif err != nil && strings.Contains(err.Error(), \"failed to raise ulimit to IPFS_FD_MAX\") {\n    log.Warnf(\"continuing below requested IPFS_FD_MAX: %v\", err)\n}","preventionTips":["Set systemd LimitNOFILE= (hard) to at least IPFS_FD_MAX in the unit file","Verify limits after startup by logging the returned newLimit from ManageFdLimit","Keep IPFS_FD_MAX in sync with the deployment environment's hard limits"],"tags":["ulimit","file-descriptors","configuration","go"],"backgroundTag":"ulimit-raise-denied","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}