{"record":{"id":"638e291d9b7ceeb7","repo":"nats-io/nats-server","slug":"resolver-preloads-only-available-for-writeable-res","errorCode":null,"errorMessage":"resolver preloads only available for writeable resolver types MEM/DIR/CACHE_DIR","messagePattern":"resolver preloads only available for writeable resolver types MEM/DIR/CACHE_DIR","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/server.go","lineNumber":1514,"sourceCode":"\ts.accResolver = opts.AccountResolver\n\tif opts.AccountResolver != nil {\n\t\t// For URL resolver, set the TLSConfig if specified.\n\t\tif opts.AccountResolverTLSConfig != nil {\n\t\t\tif ar, ok := opts.AccountResolver.(*URLAccResolver); ok {\n\t\t\t\tif t, ok := ar.c.Transport.(*http.Transport); ok {\n\t\t\t\t\tt.CloseIdleConnections()\n\t\t\t\t\tt.TLSClientConfig = opts.AccountResolverTLSConfig.Clone()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif len(opts.resolverPreloads) > 0 {\n\t\t\t// Lock ordering is account resolver -> server, so we need to release\n\t\t\t// the lock and reacquire it when done with account resolver's calls.\n\t\t\tar := s.accResolver\n\t\t\ts.mu.Unlock()\n\t\t\tdefer s.mu.Lock()\n\t\t\tif ar.IsReadOnly() {\n\t\t\t\treturn fmt.Errorf(\"resolver preloads only available for writeable resolver types MEM/DIR/CACHE_DIR\")\n\t\t\t}\n\t\t\tfor k, v := range opts.resolverPreloads {\n\t\t\t\t_, err := jwt.DecodeAccountClaims(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"preload account error for %q: %v\", k, err)\n\t\t\t\t}\n\t\t\t\tar.Store(k, v)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// This will check preloads for validation issues.\nfunc (s *Server) checkResolvePreloads() {\n\topts := s.getOpts()\n\t// We can just check the read-only opts versions here, that way we do not need\n\t// to grab server lock or access s.accResolver.","sourceCodeStart":1496,"sourceCodeEnd":1532,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/server.go#L1496-L1532","documentation":"Resolver preloading (`resolver_preload` in config) is only supported for resolvers that can store data locally: MEM, DIR, and CACHE_DIR. The configured account resolver is read-only (e.g. a plain URL resolver), so preloading has no place to write and startup fails. This is a configuration validation check in ProcessOptions.","triggerScenarios":"Config combines `resolver = URL(...)` (read-only) with a non-empty `resolver_preload` map; opts.resolverPreloads is iterated only after ar.IsReadOnly() returns true, returning this error immediately.","commonSituations":"Copying a full standalone-server config (MEM resolver + preloads) into an operator/spoke setup that uses a URL resolver; forgetting that nats-server 2.x splits 'resolver' (URL) from local storage resolvers.","solutions":["Remove the `resolver_preload` block from the config if using a URL resolver","Switch to a writeable resolver: `resolver: MEMORY` or `resolver: DIR /path` and keep the preloads","Use CACHE_DIR resolver if you want URL fetching plus local caching and preloads"],"exampleFix":"// before\nresolver = URL(http://localhost:9090)\nresolver_preload = { ACC: \"eyJ...\" }\n// after\nresolver = MEMORY\nresolver_preload = { ACC: \"eyJ...\" }","handlingStrategy":"validation","validationCode":"// Check config consistency before handing it to the server\nfunc preloadAllowed(resolver string, preloads map[string]string) error {\n    writeable := map[string]bool{\"MEM\": true, \"DIR\": true, \"CACHE_DIR\": true}\n    if len(preloads) > 0 && !writeable[strings.ToUpper(resolver)] {\n        return fmt.Errorf(\"resolver_preload requires MEM/DIR/CACHE_DIR, got %q\", resolver)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only set resolver_preload with resolver: MEMORY or DIR/CACHE_DIR","Keep separate config templates for leaf/spoke (URL resolver) vs standalone (MEM) setups","Lint configs in CI to reject preload+URL-resolver combinations"],"tags":["nats-server","resolver","configuration","preload"],"backgroundTag":"invalid-resolver-configuration","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}