{"record":{"id":"51c21d341c63658d","repo":"shadowsocks/shadowsocks-rust","slug":"invalid-online-config-version","errorCode":null,"errorMessage":"invalid online config version","messagePattern":"invalid online config version","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/shadowsocks-service/src/config.rs","lineNumber":2115,"sourceCode":"\n                        nconfig.local.push(local_instance);\n                    }\n                }\n            }\n            ConfigType::Server | ConfigType::Manager => {\n                // NOTE: IGNORED.\n                // servers only uses `local_address` for binding outbound interfaces\n                //\n                // This behavior causes lots of confusion. use outbound_bind_addr instead\n            }\n            #[cfg(feature = \"local-online-config\")]\n            ConfigType::OnlineConfig => {\n                // SIP008. https://shadowsocks.org/doc/sip008.html\n                // \"version\" should be set to \"1\"\n                match config.version {\n                    Some(1) => {}\n                    Some(v) => {\n                        let err = Error::new(\n                            ErrorKind::Invalid,\n                            \"invalid online config version\",\n                            Some(format!(\"version: {v}\")),\n                        );\n                        return Err(err);\n                    }\n                    None => {\n                        warn!(\n                            \"OnlineConfig \\\"version\\\" is missing in the configuration, assuming it is a compatible version for this project\"\n                        );\n                    }\n                }\n            }\n        }\n\n        let server_source = match config_type {\n            ConfigType::Local | ConfigType::Server | ConfigType::Manager => ServerSource::Configuration,\n            #[cfg(feature = \"local-online-config\")]","sourceCodeStart":2097,"sourceCodeEnd":2133,"githubUrl":"https://github.com/shadowsocks/shadowsocks-rust/blob/8eb0f0a65b1d976ab6bed5787327ef86529b0435/crates/shadowsocks-service/src/config.rs#L2097-L2133","documentation":"Thrown when validating a SIP008 online config: the `version` field must be exactly 1 (per SIP008 spec at shadowsocks.org/doc/sip008.html). Any other numeric version is rejected with ErrorKind::Invalid.","triggerScenarios":"Calling Config::load_from_json (ConfigType::OnlineConfig) with a JSON document whose `version` is 0, 2, a string like \"1\", or absent-but-nonconforming value.","commonSituations":"Third-party SIP008 providers emitting version 2 or omitting/bumping the field; hand-written JSON with `\"version\": \"1\"` (string, not integer); auto-generated configs from newer/older tooling.","solutions":["Set `\"version\": 1` (integer) in the SIP008 JSON document","Ask the config provider to emit SIP008 version 1","If hand-editing, ensure version is a JSON number, not a string"],"exampleFix":"// before\n{\"version\": 2, \"servers\": [...]}\n// after\n{\"version\": 1, \"servers\": [...]}","handlingStrategy":"validation","validationCode":"fn check_sip008_version(doc: &serde_json::Value) -> Result<(), String> {\n    match doc.get(\"version\") {\n        Some(serde_json::Value::Number(n)) if n.as_i64() == Some(1) => Ok(()),\n        other => Err(format!(\"expected version 1 (integer), got {:?}\", other)),\n    }\n}","typeGuard":null,"tryCatchPattern":"match Config::load_from_json(...) { Err(e) if format!(\"{e}\").contains(\"online config version\") => sanitize_and_retry(), ... }","preventionTips":["Normalize third-party SIP008 documents to version 1 before loading","Ensure version is a JSON number, not a string","Pin providers to SIP008 v1 output"],"tags":["sip008","config","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"8eb0f0a65b1d976ab6bed5787327ef86529b0435","analyzedAt":"2026-09-09T12:20:43.168Z","contentChangedAt":"2026-09-09T12:20:43.168Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}