{"record":{"id":"7d5d0f1e559afc36","repo":"hatoo/oha","slug":"invalid-aws-credentials-format-expected-access-ke","errorCode":null,"errorMessage":"Invalid AWS credentials format. Expected access_key:secret_key","messagePattern":"Invalid AWS credentials format\\. Expected access_key:secret_key","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":354,"sourceCode":"        help = \"Number of native OS threads used by the async runtime (tokio). Defaults to the number of physical CPU cores.\",\n        long = \"worker-threads\",\n        env = \"TOKIO_WORKER_THREADS\",\n        default_value_t = std::num::NonZeroUsize::new(num_cpus::get_physical())\n            .unwrap_or(std::num::NonZeroUsize::MIN)\n    )]\n    worker_threads: std::num::NonZeroUsize,\n}\n\nasync fn run(mut opts: Opts) -> anyhow::Result<()> {\n    let work_mode = opts.work_mode();\n    let url = opts.url.expect(\"URL is required\");\n\n    // Parse AWS credentials from basic auth if AWS signing is requested\n    let aws_config = if let Some(signing_params) = opts.aws_sigv4 {\n        if let Some(auth) = &opts.basic_auth {\n            let parts: Vec<&str> = auth.split(':').collect();\n            if parts.len() != 2 {\n                anyhow::bail!(\"Invalid AWS credentials format. Expected access_key:secret_key\");\n            }\n            let access_key = parts[0];\n            let secret_key = parts[1];\n            let session_token = opts.aws_session.take();\n            Some(AwsSignatureConfig::new(\n                access_key,\n                secret_key,\n                &signing_params,\n                session_token,\n            )?)\n        } else {\n            anyhow::bail!(\"AWS credentials (--auth) required when using --aws-sigv4\");\n        }\n    } else {\n        None\n    };\n\n    let parse_http_version = |is_http2: bool, version: Option<&str>| match (is_http2, version) {","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/hatoo/oha/blob/4efba2d113d165aaaf7533f5d2893e7cc57ebfc1/src/main.rs#L336-L372","documentation":"When --aws-sigv4 is requested, run() derives AWS credentials from the --auth basic-auth string by splitting it on ':' and requiring exactly two parts: access_key and secret_key. If the string does not contain exactly one colon, the run aborts before any requests are made.","triggerScenarios":"Passing --aws-sigv4 with an --auth value that splits into != 2 parts on ':', e.g. `--auth AKID` (no colon) or `--auth AKID:secret:extra` (two colons).","commonSituations":"Users forget that --auth doubles as AWS credential carrier when --aws-sigv4 is set; secret keys are fine but users paste `access:secret` plus a session token into the same string; shell expansion or quoting strips the colon.","solutions":["Provide --auth as exactly `access_key:secret_key` when using --aws-sigv4.","Move any session token to the dedicated --aws-session-token option instead of appending it to --auth.","Quote the argument so the shell does not mangle the colon-containing value."],"exampleFix":"// before\noha --aws-sigv4 \"aws:amz:us-east-1:s3\" --auth AKIDEXAMPLE --aws-session-token TOK https://...\n// after\noha --aws-sigv4 \"aws:amz:us-east-1:s3\" --auth AKIDEXAMPLE:secretKey --aws-session-token TOK https://...","handlingStrategy":"validation","validationCode":"fn valid_aws_auth(auth: &str) -> bool {\n    let parts: Vec<&str> = auth.split(':').collect();\n    parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty()\n}","typeGuard":null,"tryCatchPattern":"match run(opts).await {\n    Err(e) if e.to_string().contains(\"Invalid AWS credentials format\") => {\n        eprintln!(\"--auth must be access_key:secret_key (exactly one colon)\");\n    }\n    Err(e) => return Err(e),\n    Ok(v) => v,\n}","preventionTips":["When --aws-sigv4 is set, put only access_key:secret_key in --auth.","Pass session tokens via --aws-session-token, never inline in --auth.","Quote the argument: --auth \"$AWS_KEY:$AWS_SECRET\"."],"tags":["aws","cli","credentials","sigv4"],"backgroundTag":"invalid-argument-format","analyzedSha":"4efba2d113d165aaaf7533f5d2893e7cc57ebfc1","analyzedAt":"2026-09-09T16:24:23.306Z","contentChangedAt":"2026-09-09T16:24:23.306Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}