ipfs/kubo · critical
reading repo config: %w
Error message
reading repo config: %w
What it means
MountKeystoreDatastores reads the repo configuration to locate the root datastore spec before mounting the alternating keystore datastores. If repo.Config() fails, the error is wrapped as "reading repo config: %w" so the underlying cause (lock, corruption, permissions, malformed file) is preserved. It is raised during node construction, in the openDiagDatastore path, so a node startup failure with this message means the repo itself could not be read, not that the keystore logic failed.
Source
Thrown at core/node/provider.go:455
}
return spec
default:
if _, hasChild := spec["child"]; hasChild {
providerLog.Warnw("unrecognized datastore wrapper type, using as-is",
"type", spec["type"])
}
return spec
}
}
// MountKeystoreDatastores opens any provider keystore datastores that exist on
// disk and returns them as mount.Mount entries ready to be combined with the
// main repo datastore. The caller must call the returned cleanup function when
// done. Returns nil mounts and a no-op closer if no keystores exist.
func MountKeystoreDatastores(repo repo.Repo) ([]mount.Mount, func(), error) {
cfg, err := repo.Config()
if err != nil {
return nil, nil, fmt.Errorf("reading repo config: %w", err)
}
rootSpec := findRootDatastoreSpec(cfg.Datastore.Spec)
if rootSpec == nil {
return nil, func() {}, nil
}
keystoreBasePath := filepath.Join(repo.Path(), KeystoreDatastorePath)
var mounts []mount.Mount
var closers []func()
for _, suffix := range []string{"0", "1"} {
dir := filepath.Join(keystoreBasePath, suffix)
if _, err := os.Stat(dir); err != nil {
continue
}
ds, err := openDatastoreAt(rootSpec, dir)
if err != nil {View on GitHub (pinned to 329838acdf)
Solutions
- Read the wrapped cause at the end of the error chain and fix that specific problem first (it names the real failure).
- Check for a stale repo lock: ensure no other ipfs daemon is running (pkill -f "ipfs daemon") and remove the lockfile only if no process holds it.
- Verify IPFS_PATH points at an initialized repo and that $IPFS_PATH/config is valid JSON (ipfs config show).
- Fix file permissions/ownership on the config file so the current user can read it.
- If the config is corrupted, restore from backup or re-init the repo (data loss risk — copy the datastore first).
Example fix
// before (diagnostic)
cfg, err := repo.Config()
if err != nil {
return nil, nil, fmt.Errorf("reading repo config: %w", err)
}
// after (caller-side guard)
cfg, err := repo.Config()
if err != nil {
if errors.Is(err, fsrepo.ErrNoRepo) {
return nil, nil, fmt.Errorf("IPFS_PATH is not an initialized repo: %w", err)
}
return nil, nil, fmt.Errorf("reading repo config: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before starting the daemon/purge:
if _, err := os.Stat(filepath.Join(os.Getenv("IPFS_PATH"), "config")); err != nil {
return fmt.Errorf("no repo config at IPFS_PATH=%s: %w", os.Getenv("IPFS_PATH"), err)
}
if _, err := os.Stat(filepath.Join(os.Getenv("IPFS_PATH"), "repo.lock")); err == nil {
// lock present: verify no live daemon before proceeding
log.Warn("repo.lock exists; ensure no other daemon is running")
} Try / catch
cfg, err := repo.Config()
if err != nil {
var cause error = err
for errors.Unwrap(cause) != nil { cause = errors.Unwrap(cause) }
switch {
case errors.Is(err, fsrepo.ErrNoRepo):
// IPFS_PATH not initialized: run `ipfs init`
case errors.Is(err, syscall.EACCES) || errors.Is(err, syscall.EPERM):
// fix file ownership/permissions on IPFS_PATH
default:
// check repo.lock / corrupted config JSON
}
return fmt.Errorf("reading repo config: %w", err)
} Prevention
- Never run two daemons against the same IPFS_PATH
- Set IPFS_PATH explicitly in scripts and test harnesses
- Validate config JSON after hand edits with `ipfs config show`
- Back up $IPFS_PATH/config before upgrades or profile changes
When it happens
Trigger: Calling MountKeystoreDatastores(repo) (directly or via openDiagDatastore during daemon startup) when the underlying repo.Config() call errors — e.g. repo locked by another process, config file unreadable, invalid JSON, or unsupported config version.
Common situations: Two daemons running against the same IPFS_PATH (repo lock held); ~/.ipfs/config corrupted by a partial edit or disk-full write; wrong IPFS_PATH pointing at a non-repo directory; permission problems after running the daemon as different users.
Related errors
- could not read config: %w
- ipfs not initialized, please run 'ipfs init'
- cannot access config, repo not open
- serveHTTPGateway: GetConfig() failed: %s
- cannot create libp2p gateway: node PeerHost is nil (this sho
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/bec34572a38aee1a.
Report an issue: GitHub.