{"record":{"id":"14a8330025ae0ce4","repo":"apache/pulsar","slug":"failed-to-write-cookie-for-bookie-bookieid","errorCode":null,"errorMessage":"Failed to write cookie for bookie ${bookieId}","messagePattern":"Failed to write cookie for bookie (.+?)","errorType":"exception","errorClass":"BookieException.MetadataStoreException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarRegistrationManager.java","lineNumber":246,"sourceCode":"                version = -1L;\n            } else {\n                if (!(cookieData.getVersion() instanceof LongVersion)) {\n                    throw new BookieException.BookieIllegalOpException(\n                            \"Invalid version type, expected it to be LongVersion\");\n                }\n                version = ((LongVersion) cookieData.getVersion()).getLongVersion();\n            }\n\n            store.put(path, cookieData.getValue(), Optional.of(version))\n                    .get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);\n        } catch (InterruptedException ie) {\n            Thread.currentThread().interrupt();\n            throw new BookieException.MetadataStoreException(\"Interrupted writing cookie for bookie \" + bookieId, ie);\n        } catch (ExecutionException e) {\n            if (e.getCause() instanceof MetadataStoreException.BadVersionException) {\n                throw new BookieException.CookieExistException(bookieId.toString());\n            } else {\n                throw new BookieException.MetadataStoreException(\"Failed to write cookie for bookie \" + bookieId);\n            }\n        } catch (TimeoutException ex) {\n            throw new BookieException.MetadataStoreException(\"Failed to write cookie for bookie \" + bookieId, ex);\n        }\n    }\n\n    @Override\n    public Versioned<byte[]> readCookie(BookieId bookieId) throws BookieException {\n        String path = this.cookiePath + \"/\" + bookieId;\n        try {\n            Optional<GetResult> res = store.get(path).get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);\n            if (!res.isPresent()) {\n                throw new BookieException.CookieNotFoundException(bookieId.toString());\n            }\n\n            // sets stat version from MetadataStore\n            LongVersion version = new LongVersion(res.get().getStat().getVersion());\n            return new Versioned<>(res.get().getValue(), version);","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/bookkeeper/PulsarRegistrationManager.java#L228-L264","documentation":"This is writeCookie's generic failure path: the underlying MetadataStore put failed (an ExecutionException whose cause is NOT a BadVersionException), so the cookie could not be written for the bookie. The manager discards the cause here and throws BookieException.MetadataStoreException('Failed to write cookie for bookie <bookieId>') without it, meaning the real store-side error must be found in the store's own logs. It indicates a metadata-store connectivity, permission, session, or internal failure rather than a version conflict (which raises CookieExistException instead).","triggerScenarios":"store.put(path, cookieData, Optional.of(version)) completes exceptionally with any cause other than MetadataStoreException.BadVersionException — e.g. connection loss, session expired, no auth/permission on the cookie z-node/prefix, or store-client internal error.","commonSituations":"Metadata service (ZooKeeper/etcd) unreachable or session expired while the bookie starts; wrong metadataServiceUri/credentials so writes to the /ledgers/cookies path are denied; metadata store read-only or quota exceeded; transient network partition during bookie bootstrap.","solutions":["Check the metadata store's client/server logs for the underlying cause around this timestamp (the exception itself does not carry it).","Verify metadataServiceUri connectivity and that the bookie's credentials allow writing under the cookie path (/ledgers/cookies).","Restart the bookie once the metadata store is healthy — cookie writes are retried at startup.","If failures are persistent, inspect store-side health: ZooKeeper ensemble, etcd cluster state, auth ACLs, and network paths."],"exampleFix":"// before (server-side)\n} else {\n    throw new BookieException.MetadataStoreException(\"Failed to write cookie for bookie \" + bookieId);\n}\n\n// after (preserve the cause for diagnosis)\n} else {\n    throw new BookieException.MetadataStoreException(\n            \"Failed to write cookie for bookie \" + bookieId, e.getCause());\n}","handlingStrategy":"retry","validationCode":"// check metadata store reachability before cookie operations\nstore.exists(cookiePath).get(BLOCKING_CALL_TIMEOUT, MILLISECONDS);","typeGuard":null,"tryCatchPattern":"try {\n    regManager.writeCookie(bookieId, cookie);\n} catch (BookieException.MetadataStoreException e) {\n    // cause is dropped server-side: check store logs, then retry with backoff\n    if (!Thread.currentThread().isInterrupted() && attempts < MAX_ATTEMPTS) {\n        Thread.sleep(BACKOFF_MS);\n        regManager.writeCookie(bookieId, cookie);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Monitor metadata store availability and quorum before/while bookies bootstrap.","Verify metadataServiceUri, credentials, and ACLs grant write access to the cookie path.","Prefer bookie auto-restart with backoff so transient store failures self-heal.","Because the exception drops the cause, always correlate with metadata store client logs to find the real error."],"tags":["bookkeeper","metadata-store","cookie","connectivity","zookeeper"],"backgroundTag":"metadata-store-write-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}