{"record":{"id":"69b3ad9c82ef98b7","repo":"binary-husky/gpt_academic","slug":"ssl-certfile-must-be-provided-if-ssl-keyfile-is-pr","errorCode":null,"errorMessage":"ssl_certfile must be provided if ssl_keyfile is provided.","messagePattern":"ssl_certfile must be provided if ssl_keyfile is provided\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"shared_utils/fastapi_server.py","lineNumber":292,"sourceCode":"\n    # --- --- uvicorn.Config --- ---\n    ssl_keyfile = None if SSL_KEYFILE == \"\" else SSL_KEYFILE\n    ssl_certfile = None if SSL_CERTFILE == \"\" else SSL_CERTFILE\n    server_name = \"0.0.0.0\"\n    config = uvicorn.Config(\n        fastapi_app,\n        host=server_name,\n        port=PORT,\n        reload=False,\n        log_level=\"warning\",\n        ssl_keyfile=ssl_keyfile,\n        ssl_certfile=ssl_certfile,\n    )\n    server = Server(config)\n    url_host_name = \"localhost\" if server_name == \"0.0.0.0\" else server_name\n    if ssl_keyfile is not None:\n        if ssl_certfile is None:\n            raise ValueError(\n                \"ssl_certfile must be provided if ssl_keyfile is provided.\"\n            )\n        path_to_local_server = f\"https://{url_host_name}:{PORT}/\"\n    else:\n        path_to_local_server = f\"http://{url_host_name}:{PORT}/\"\n    if CUSTOM_PATH != '/':\n        path_to_local_server += CUSTOM_PATH.lstrip('/').rstrip('/') + '/'\n    # --- --- begin  --- ---\n    server.run_in_thread()\n\n    # --- --- after server launch --- ---\n    app_block.server = server\n    app_block.server_name = server_name\n    app_block.local_url = path_to_local_server\n    app_block.protocol = (\n        \"https\"\n        if app_block.local_url.startswith(\"https\") or app_block.is_colab\n        else \"http\"","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/shared_utils/fastapi_server.py#L274-L310","documentation":"After constructing the uvicorn Server with ssl_keyfile and ssl_certfile from config, the code raises ValueError('ssl_certfile must be provided if ssl_keyfile is provided.') when SSL is half-configured. Note the check runs after Server(config) creation — uvicorn itself may already have validated/failed on the same malformed config before this line.","triggerScenarios":"Setting ssl_keyfile (e.g. via server config/CUSTOM_PATH https options) without a matching ssl_certfile, then launching the fastapi server; HTTPS requires both halves of the key/certificate pair.","commonSituations":"Configuring HTTPS with only a private key generated (cert creation step skipped); typos in one of the two variable names; copying an example config that filled only one field.","solutions":["Provide ssl_certfile alongside ssl_keyfile (generate a self-signed pair if needed: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes).","Or clear both settings to serve plain HTTP.","Verify both files exist and are readable by the service user."],"exampleFix":"# before\nssl_keyfile = \"key.pem\"\nssl_certfile = None\n\n# after\nssl_keyfile = \"key.pem\"\nssl_certfile = \"cert.pem\"","handlingStrategy":"validation","validationCode":"if (ssl_keyfile is None) != (ssl_certfile is None):\n    raise ValueError('ssl_keyfile and ssl_certfile must be set together')\nif ssl_keyfile:\n    import os\n    assert os.path.exists(ssl_keyfile) and os.path.exists(ssl_certfile), 'ssl files missing'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always provision key and certificate as a pair.","Validate both paths exist before server startup.","Use a config linter that rejects half-set HTTPS options."],"tags":["ssl","tls","server-startup","configuration","uvicorn"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}