{"record":{"id":"c21c9b5cf3e54bb8","repo":"risingwavelabs/risingwave","slug":"failed-to-parse-ldap-url","errorCode":null,"errorMessage":"Failed to parse ldap url","messagePattern":"Failed to parse ldap url","errorType":"exception","errorClass":"PsqlError","httpStatus":null,"severity":"error","filePath":"src/utils/pgwire/src/ldap_auth.rs","lineNumber":282,"sourceCode":"            LDAP_SERVER_KEY,\n            LDAP_PORT_KEY,\n            LDAP_SCHEME_KEY,\n            LDAP_BASE_DN_KEY,\n            LDAP_SEARCH_ATTRIBUTE_KEY,\n            LDAP_SEARCH_FILTER_KEY,\n        ];\n\n        for param in &conflicting_params {\n            if options.contains_key(*param) {\n                return Err(PsqlError::StartupError(\n                    format!(\"Cannot specify both ldapurl and {} parameter\", param).into(),\n                ));\n            }\n        }\n\n        // Parse the URL using standard URL parsing\n        let url = url::Url::parse(ldap_url).map_err(|e| {\n            PsqlError::StartupError(anyhow!(e).context(\"Failed to parse ldap url\").into())\n        })?;\n\n        // Validate scheme\n        let scheme = url.scheme();\n        if scheme != \"ldap\" && scheme != \"ldaps\" {\n            return Err(PsqlError::StartupError(\n                \"LDAP URL scheme must be either 'ldap' or 'ldaps'\".into(),\n            ));\n        }\n\n        // Extract host and port\n        let host = url\n            .host_str()\n            .ok_or_else(|| PsqlError::StartupError(\"LDAP URL must contain a host\".into()))?;\n        let port = url\n            .port()\n            .unwrap_or_else(|| if scheme == \"ldaps\" { 636 } else { 389 });\n","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/utils/pgwire/src/ldap_auth.rs#L264-L300","documentation":"from_ldap_url parses the configured LDAP connection string with url::Url::parse before any network activity. If the string is not a valid URL (bad scheme-less text, illegal characters, unparseable host/port), the error is wrapped as this StartupError. The library validates the scheme next, but this error fires strictly on URL syntax failure.","triggerScenarios":"url::Url::parse(ldap_url) returns Err — e.g. missing scheme, spaces or control characters in the URL, invalid port, empty string","commonSituations":"ldap_url config field set to 'ldapserver.corp' (no ldap:// scheme); copy-paste included quotes or whitespace; port written as 'ldap:389x'; templated/interpolated variable left empty at runtime.","solutions":["Include an explicit scheme: ldap://host:port or ldaps://host:port","Validate with a quick parse (curl or python -c \"import urllib.parse;urllib.parse.urlparse(...)\") before committing the config","Strip surrounding quotes/spaces from the configured value","Check that the env var/secret feeding ldap_url is actually populated, not empty"],"exampleFix":"// before\nldap_url = 'ldap.corp.local:636'\n// after\nldap_url = 'ldaps://ldap.corp.local:636'","handlingStrategy":"validation","validationCode":"fn validate_ldap_url(u: &str) -> Result<(), String> {\n    let parsed = url::Url::parse(u).map_err(|e| format!(\"invalid ldap url: {e}\"))?;\n    match parsed.scheme() {\n        \"ldap\" | \"ldaps\" => Ok(()),\n        s => Err(format!(\"bad scheme: {s} (expected ldap or ldaps)\")),\n    }\n}","typeGuard":"fn is_valid_ldap_url(u: &str) -> bool {\n    url::Url::parse(u).map(|p| p.scheme() == \"ldap\" || p.scheme() == \"ldaps\").unwrap_or(false)\n}","tryCatchPattern":"catch PsqlError::StartupError at connection-creation time and log the configured ldap_url (redacted) alongside the url::ParseError for fast diagnosis","preventionTips":["Keep a validated connection-string template in deployment docs","Validate ldap_url in config linting/startup scripts before the DB starts","Never build the URL by naive string concatenation of host and port without a scheme","Trim whitespace and quotes from env-supplied values before assignment"],"tags":["ldap","url","config","startup"],"backgroundTag":"invalid-url-format","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}