{"record":{"id":"993ea84314db4597","repo":"apache/superset","slug":"invalid-connection-string-a-valid-string-usually","errorCode":null,"errorMessage":"Invalid connection string, a valid string usually follows: backend+driver://user:password@database-host/database-name","messagePattern":"Invalid connection string, a valid string usually follows: backend\\+driver://user:password@database-host/database-name","errorType":"validation","errorClass":"ValidationError","httpStatus":422,"severity":"error","filePath":"superset/databases/schemas.py","lineNumber":214,"sourceCode":"        \"get\": {\n            \"summary\": \"Get a list of databases\",\n            \"description\": \"Gets a list of databases, use Rison or JSON query \"\n            \"parameters for filtering, sorting, pagination and \"\n            \" for selecting specific columns and metadata.\",\n        }\n    },\n    \"info\": {\"get\": {\"summary\": \"Get metadata information about this API resource\"}},\n}\n\n\ndef sqlalchemy_uri_validator(value: str) -> str:\n    \"\"\"\n    Validate if it's a valid SQLAlchemy URI and refuse SQLLite by default\n    \"\"\"\n    try:\n        uri = make_url_safe(value.strip())\n    except DatabaseInvalidError as ex:\n        raise ValidationError(\n            [\n                _(\n                    \"Invalid connection string, a valid string usually follows: \"\n                    \"backend+driver://user:password@database-host/database-name\"\n                )\n            ]\n        ) from ex\n    if current_app.config.get(\"PREVENT_UNSAFE_DB_CONNECTIONS\", True):\n        try:\n            check_sqlalchemy_uri(uri)\n        except SupersetSecurityException as ex:\n            raise ValidationError([str(ex)]) from ex\n    return value\n\n\ndef server_cert_validator(value: str) -> str:\n    \"\"\"\n    Validate the server certificate","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/apache/superset/blob/f4587218dd19d046c3e4d00063e7d27f8a2ed354/superset/databases/schemas.py#L196-L232","documentation":"Field validator for the SQLAlchemy URI on database create/update: make_url_safe (SQLAlchemy make_url) failed to parse the string as a URI, so the value cannot possibly be used as a connection string. The message shows the canonical backend+driver://user:password@host/db shape.","triggerScenarios":"POST/PUT /api/v1/database/ with sqlalchemy_uri that is empty-ish, lacks a scheme/delimiter, uses backslashes or spaces, or is a DSN in a dialect SQLAlchemy does not understand (e.g. an ODBC or JDBC string pasted verbatim).","commonSituations":"Pasting JDBC URLs (jdbc:postgresql://...) or pyodbc connection strings; missing '://'; typos like postgres://:host/db; copying URIs with quotes/newlines from password managers.","solutions":["Rewrite the URI in SQLAlchemy form: dialect+driver://user:password@host:port/database (e.g. postgresql+psycopg2://...).","Strip whitespace, quotes, and newlines; ensure the password is URL-encoded if it contains special characters like @ or :.","Test locally: from sqlalchemy.engine import make_url; make_url(uri).","For ODBC/JDBC sources, use the corresponding SQLAlchemy dialect URI rather than the native DSN."],"exampleFix":"# before\njdbc:postgresql://dbhost:5432/analytics\n\n# after\npostgresql+psycopg2://user:p%40ssw0rd@dbhost:5432/analytics","handlingStrategy":"validation","validationCode":"from sqlalchemy.engine import make_url\ntry:\n    make_url(uri.strip())\nexcept Exception as e:\n    raise ValueError(f\"not a valid SQLAlchemy URI: {e}\")","typeGuard":"def is_valid_sqlalchemy_uri(uri: str) -> bool:\n    try:\n        make_url(uri.strip())\n        return True\n    except Exception:\n        return False","tryCatchPattern":null,"preventionTips":["Use dialect+driver://user:password@host:port/database form; URL-encode credentials.","Test with sqlalchemy.engine.make_url before submitting.","Convert JDBC/ODBC DSNs to their SQLAlchemy dialect equivalents."],"tags":["database","sqlalchemy","uri","validation"],"backgroundTag":null,"analyzedSha":"f4587218dd19d046c3e4d00063e7d27f8a2ed354","analyzedAt":"2026-08-14T22:39:27.425Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}