apache/hadoop · error · IllegalArgumentException
Proxy error: %s or %s set without the other.
Error message
Proxy error: %s or %s set without the other.
What it means
DefaultOBSClientFactory reads fs.obs.proxy.username (getTrimmed) and fs.obs.proxy.password (getPassword) when setting up the HTTP proxy for the OBS client. If exactly one of the two is configured (XOR check), initialization aborts with IllegalArgumentException 'Proxy error: fs.obs.proxy.username or fs.obs.proxy.password set without the other.' The OBS SDK requires both credentials together, so a half-configured proxy is rejected before any connection is attempted.
Source
Thrown at hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/DefaultOBSClientFactory.java:197
LOG.warn("Proxy host set without port. Using HTTP default "
+ OBSConstants.DEFAULT_HTTP_PORT);
obsConf.getHttpProxy()
.setProxyPort(OBSConstants.DEFAULT_HTTP_PORT);
}
}
String proxyUsername = conf.getTrimmed(OBSConstants.PROXY_USERNAME);
String proxyPassword = null;
char[] proxyPass = conf.getPassword(OBSConstants.PROXY_PASSWORD);
if (proxyPass != null) {
proxyPassword = new String(proxyPass).trim();
}
if ((proxyUsername == null) != (proxyPassword == null)) {
String msg =
"Proxy error: " + OBSConstants.PROXY_USERNAME + " or "
+ OBSConstants.PROXY_PASSWORD
+ " set without the other.";
LOG.error(msg);
throw new IllegalArgumentException(msg);
}
obsConf.setHttpProxy(proxyHost, proxyPort, proxyUsername,
proxyPassword);
if (LOG.isDebugEnabled()) {
LOG.debug(
"Using proxy server {}:{} as user {} on "
+ "domain {} as workstation {}",
obsConf.getHttpProxy().getProxyAddr(),
obsConf.getHttpProxy().getProxyPort(),
obsConf.getHttpProxy().getProxyUName(),
obsConf.getHttpProxy().getDomain(),
obsConf.getHttpProxy().getWorkstation());
}
}
/**
* Creates an {@link ObsClient} from the established configuration.
*View on GitHub (pinned to 2add963021)
Solutions
- Set BOTH fs.obs.proxy.username and fs.obs.proxy.password (or remove both to disable authenticated proxy).
- If the password comes from a credential provider, verify the entry exists: hadoop credential list -provider jceks://... and confirm the provider path config resolves in the same context (same user/classpath).
- Check for typos: keys are exactly fs.obs.proxy.username / fs.obs.proxy.password; per-bucket variants must mirror each other.
- If the proxy truly needs no auth, clear both keys and rely on fs.obs.proxy.host + fs.obs.proxy.port only.
Example fix
# before (core-site.xml) <property><name>fs.obs.proxy.host</name><value>proxy.corp</value></property> <property><name>fs.obs.proxy.port</name><value>8080</value></property> <property><name>fs.obs.proxy.username</name><value>obsuser</value></property> <!-- password missing --> # after <property><name>fs.obs.proxy.username</name><value>obsuser</value></property> <property><name>fs.obs.proxy.password</name><value>obs-pass</value></property> <!-- or store via: hadoop credential create fs.obs.proxy.password -value xxx -provider localjceks://...</property -->
Defensive patterns
Strategy: validation
Validate before calling
static boolean proxyConfigConsistent(Configuration conf) {
String u = conf.getTrimmed("fs.obs.proxy.username");
char[] p = conf.getPassword("fs.obs.proxy.password");
return (u == null) == (p == null); // both set or both unset
}
if (!proxyConfigConsistent(conf)) throw new ConfigException("set both fs.obs.proxy.username and fs.obs.proxy.password"); Try / catch
try {
obsFs.initialize(uri, conf);
} catch (IllegalArgumentException e) {
if (String.valueOf(e.getMessage()).contains("fs.obs.proxy.username")) {
if (String.valueOf(e.getMessage()).contains("Proxy error")) {
throw new ConfigException("Proxy credentials half-configured", e);
}
}
throw e;
} Prevention
- Config-lint all paired keys (host/port/user/password) at deploy time.
- Prefer credential-provider entries for proxy passwords; verify with hadoop credential list.
- Per-bucket overrides must mirror base keys: if you override username, override password too.
When it happens
Trigger: Setting fs.obs.proxy.username in core-site.xml (or a job config) without fs.obs.proxy.password; providing the password only via a credential provider that fails to resolve (getPassword returns null → password side missing); trailing-whitespace/empty username trimmed to null; per-bucket config override (fs.obs.bucket.X.proxy.username) that forgets the matching password key.
Common situations: Adding proxy settings incrementally during corporate-network onboarding; copy-pasting an example config that only shows the username line; password moved to a JCEKS credential provider that is not on hadoop.security.credential.provider.path, so getPassword() yields null; typos in one of the two key names.
Related errors
- From option %s %s
- Bucket {} does not exist
- Filesystem %s closed
- write has error. bs : pre upload obs[%s] has error.
- closed has error. bs : pre write obs[%s] has error.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/c2d168a40da72a1b.
Report an issue: GitHub.