{"record":{"id":"95140b33d7696011","repo":"elastic/elasticsearch","slug":"database-is-read-only","errorCode":null,"errorMessage":"Database {} is read only","messagePattern":"Database (.+?) is read only","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/direct/PutDatabaseConfigurationAction.java","lineNumber":54,"sourceCode":"\n        public Request(TimeValue masterNodeTimeout, TimeValue ackTimeout, DatabaseConfiguration database) {\n            super(masterNodeTimeout, ackTimeout);\n            this.database = database;\n        }\n\n        public Request(StreamInput in) throws IOException {\n            super(in);\n            database = new DatabaseConfiguration(in);\n        }\n\n        public DatabaseConfiguration getDatabase() {\n            return this.database;\n        }\n\n        public static Request parseRequest(TimeValue masterNodeTimeout, TimeValue ackTimeout, String id, XContentParser parser) {\n            DatabaseConfiguration database = DatabaseConfiguration.parse(parser, id);\n            if (database.isReadOnly()) {\n                throw new IllegalArgumentException(\"Database \" + id + \" is read only\");\n            } else {\n                return new Request(masterNodeTimeout, ackTimeout, database);\n            }\n        }\n\n        @Override\n        public void writeTo(StreamOutput out) throws IOException {\n            super.writeTo(out);\n            database.writeTo(out);\n        }\n\n        @Override\n        public ActionRequestValidationException validate() {\n            return database.validate();\n        }\n\n        @Override\n        public int hashCode() {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ip-location/src/main/java/org/elasticsearch/ingest/geoip/direct/PutDatabaseConfigurationAction.java#L36-L72","documentation":"Thrown by PutDatabaseConfigurationAction.parseRequest when the database configuration being PUT uses a Provider whose isReadOnly() returns true. Only writable providers (currently Maxmind and Ipinfo) may be created via PUT. Read-only providers (Local, Web) are system-managed and cannot be authored by users.","triggerScenarios":"PUT _ingest/geoip/database/<id> with a request body whose provider is 'local' or 'web', e.g. {\"name\":\"...\",\"local\":{\"type\":\"...\"}} or {\"name\":\"...\",\"web\":{}}. The check fires during request parsing, before cluster state is touched.","commonSituations":"Misunderstanding which providers are user-writable; attempting to recreate a Local database seen in GET output; mixing up the GeoIP enterprise (web/local) databases with self-hosted Maxmind databases.","solutions":["Use a writable provider in the body: 'maxmind' (with account_id) or 'ipinfo'.","If you intended a read-only database, note that Local and Web configs are managed by the system/downloader and cannot be PUT.","Remove the 'local' or 'web' key from the request body and replace with 'maxmind' or 'ipinfo'."],"exampleFix":"// before\nPUT _ingest/geoip/database/my-db\n{ \"name\": \"City\", \"web\": {} }\n\n// after\nPUT _ingest/geoip/database/my-db\n{ \"name\": \"City\", \"maxmind\": { \"account_id\": \"123456\" } }","handlingStrategy":"validation","validationCode":"// Only maxmind/ipinfo providers are writable via PUT\nString provider = body.get(\"type\"); // or detect the top-level key\nSet<String> WRITABLE = Set.of(\"maxmind\", \"ipinfo\");\nif (!WRITABLE.contains(provider)) {\n    throw new IllegalArgumentException(\"Provider \" + provider + \" is read-only; use maxmind or ipinfo\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember only 'maxmind' and 'ipinfo' are user-writable providers.","Local and Web databases are system-managed; do not attempt to PUT them.","When templating PUT bodies, restrict the provider field to writable values."],"tags":["elasticsearch","geoip","validation","provider","read-only","rest-api"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}