{"record":{"id":"12b86ea96fa99519","repo":"mem0ai/mem0","slug":"either-api-key-or-user-password-must-be-provided","errorCode":null,"errorMessage":"Either api_key or user/password must be provided","messagePattern":"Either api_key or user/password must be provided","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/configs/vector_stores/elasticsearch.py","lineNumber":34,"sourceCode":"    verify_certs: bool = Field(True, description=\"Verify SSL certificates\")\n    ca_certs: Optional[str] = Field(None, description=\"Path to CA bundle for SSL certificate verification\")\n    use_ssl: bool = Field(True, description=\"Use SSL for connection\")\n    auto_create_index: bool = Field(True, description=\"Automatically create index during initialization\")\n    custom_search_query: Optional[Callable[[List[float], int, Optional[Dict]], Dict]] = Field(\n        None, description=\"Custom search query function. Parameters: (query, top_k, filters) -> Dict\"\n    )\n    headers: Optional[Dict[str, str]] = Field(None, description=\"Custom headers to include in requests\")\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_auth(cls, values: Dict[str, Any]) -> Dict[str, Any]:\n        # Check if either cloud_id or host/port is provided\n        if not values.get(\"cloud_id\") and not values.get(\"host\"):\n            raise ValueError(\"Either cloud_id or host must be provided\")\n\n        # Check if authentication is provided\n        if not any([values.get(\"api_key\"), (values.get(\"user\") and values.get(\"password\"))]):\n            raise ValueError(\"Either api_key or user/password must be provided\")\n\n        return values\n\n    @model_validator(mode=\"before\")\n    @classmethod\n    def validate_headers(cls, values: Dict[str, Any]) -> Dict[str, Any]:\n        \"\"\"Validate headers format and content\"\"\"\n        headers = values.get(\"headers\")\n        if headers is not None:\n            # Check if headers is a dictionary\n            if not isinstance(headers, dict):\n                raise ValueError(\"headers must be a dictionary\")\n            \n            # Check if all keys and values are strings\n            for key, value in headers.items():\n                if not isinstance(key, str) or not isinstance(value, str):\n                    raise ValueError(\"All header keys and values must be strings\")\n        ","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/configs/vector_stores/elasticsearch.py#L16-L52","documentation":"Raised by the Elasticsearch config auth validator when no authentication material is present. It accepts either an api_key or the user/password pair; with neither, the config cannot authenticate to the cluster and Pydantic raises during construction.","triggerScenarios":"Creating ElasticsearchConfig with cloud_id or host set but api_key missing AND user/password missing (or only one of user/password supplied — the pair must be truthy together).","commonSituations":"Local dev against an open ES cluster that later gets security enabled; api_key stored in a vault call that silently returned None; providing user but empty password after a config templating pass; using an encoded api_key tuple where a string key is expected.","solutions":["Set 'api_key' (Elastic Cloud-encoded api key) in the config","Or set both 'user' and 'password' (basic auth), e.g. user='elastic', password from your secret store","Confirm both members of the pair are non-empty; a lone username does not pass","Load and assert secrets resolve to non-None values before constructing the config"],"exampleFix":"# before\nElasticsearchConfig(host=\"http://localhost:9200\")\n\n# after\nElasticsearchConfig(host=\"http://localhost:9200\", user=\"elastic\", password=os.environ[\"ES_PASSWORD\"])","handlingStrategy":"validation","validationCode":"def validate_es_auth(cfg: dict) -> None:\n    if not (cfg.get(\"api_key\") or (cfg.get(\"user\") and cfg.get(\"password\"))):\n        raise RuntimeError(\"Elasticsearch config needs api_key or user+password\")","typeGuard":"def es_auth_ok(cfg: dict) -> bool:\n    return bool(cfg.get(\"api_key\") or (cfg.get(\"user\") and cfg.get(\"password\")))","tryCatchPattern":"from pydantic import ValidationError\ntry:\n    ElasticsearchConfig(**cfg)\nexcept ValidationError as e:\n    if \"api_key or user/password\" in str(e):\n        # resolve the missing credential from the secret store, then retry\n        ...","preventionTips":["Assert secrets resolve to non-None before config construction","Provide user and password together, never one alone","Re-check auth after enabling security on a previously open cluster"],"tags":["pydantic","configuration","vector-store","elasticsearch","authentication"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}