Every occurrence the notifier builds — anything reported through log, debug, info,
warning, error or critical, including uncaught exceptions — is passed through a built-in
scrubber before it is sent. It runs after any Transformer you configure, so a transformer
cannot be used to opt out of it.
This applies to all three notifiers, since they share the same configuration and send path:
| Module | Covered |
|---|---|
rollbar-java |
yes |
rollbar-reactive-streams |
yes |
rollbar-android |
yes |
The exception is Rollbar.sendJsonPayload(String), which hands an already-serialized payload
straight to the sender and skips transformers, filters and scrubbing alike. Nothing on this page
applies to it; scrub that JSON yourself before passing it in.
-
Fields whose key names a secret, in the payload slots the notifier can parse — the full list of slots is below. The built-in key list is
Pattern Also matches passworduser_password,passwordConfirmation,passwordHashpasswdsecretclient_secret,secretKeytokenaccess_token,auth_token,csrfToken,refreshTokenauthorizationproxy_authorizationauthentication^auth$anchored on purpose, so authoris left aloneapikey,api_key,api-keymyApiKey,X-Api-KeyMatching is case-insensitive and, apart from
^auth$, matches anywhere in the key. SoGET /login?password=hunter2arrives withrequest.get.password,request.query_stringand therequest.urlquery all redacted. -
Request headers, matched case-insensitively against a built-in deny-list:
Authorization,Cookie,Set-Cookie,X-Api-Key,X-Auth-Token,X-Access-Token,X-Secret,Proxy-Authorization,WWW-Authenticate. The value becomes***. -
URLs, which have their userinfo, query string and fragment stripped. This covers
request.urland the URLs recorded byRollbar.recordNetworkEventFor(...), sohttps://user:pass@example.com/orders?token=secretis reported ashttps://example.com/orders.
Not covered — you should scrub these before handing them to the notifier:
request.body, a raw string the notifier cannot parse.- Telemetry event bodies. The
bodymap of a telemetry event is sent verbatim. The only protection is the URL of a network event, and that is applied when the event is recorded rather than when the payload is scrubbed, sorecordLogEventFor,recordManualEventForandrecordNavigationEventForship whatever message you give them. This matters most on Android, where the logcat capture records raw log lines from the whole app UID — third-party libraries included. data.personanddata.server, whose fields are sent exactly as yourpersonandserverproviders supply them.
redactedKeys takes a list of case-insensitive regexes, added to the built-in list above. A
key is redacted when the regex is found anywhere in it, so "pin" also matches pin_code.
Config config = ConfigBuilder.withAccessToken(ACCESS_TOKEN)
.redactedKeys(Arrays.asList("ssn", "pin", "date_of_birth"))
.build();They are matched against the keys of: request headers, routing parameters (request.params),
GET and POST parameters, request.metadata, the raw request.query_string, the metadata of a
Message body (body.message), custom data, and Frame.locals — including the copies carried
by body.threads when JVMTI locals capture is enabled. Matching values are replaced with ***.
Keys outside that set are left alone; see what is not covered above.
Empty and whitespace-only entries are ignored, so a stray blank line or trailing comma in a config file cannot turn into a pattern that matches every key.
Keys that contain no regex syntax — plain names such as ssn or x-tenant-secret, and anchored
names such as ^pin$ — are matched without running the regex engine. This is an internal
optimization with no effect on what matches, but it is why scrubbing stays cheap on Android: a
payload of ~100 keys allocates about 7 KB rather than 170 KB.
To match only your own keys, turn the built-in list off. The header deny-list and the URL sanitizer still apply:
Config config = ConfigBuilder.withAccessToken(ACCESS_TOKEN)
.redactedKeys(Arrays.asList("ssn"))
.useDefaultRedactedKeys(false)
.build();Nested data is walked recursively through maps, collections and arrays, up to 8 levels of
nesting, and the surrounding shape is preserved. Given redactedKeys(["password"]):
rollbar.error(exception, Collections.singletonMap(
"users", Arrays.asList(Collections.singletonMap("password", "hunter2"))));
// sent as: {"users": [{"password": "***"}]}When a key itself matches, its whole value is replaced rather than descended into.
Supply a StringUrlSanitizer to change or disable the URL handling:
Config config = ConfigBuilder.withAccessToken(ACCESS_TOKEN)
.urlSanitizer(url -> url) // keep URLs verbatim
.build();If you use the OkHttp interceptor, share the same sanitizer so both paths redact identically:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(RollbarOkHttpInterceptor.withSharedUrlSanitizer(
recorder, config.urlSanitizer()))
.build();See the rollbar-okhttp README for the interceptor's own sanitizer options.
This is a behaviour change: no configuration is required to get the redaction above, and it
cannot be disabled from a Transformer. If you are upgrading, expect that
- values matching the built-in key list, the header deny-list or your
redactedKeysnow arrive as***— including keys you may not consider sensitive, such astokenCount. SetuseDefaultRedactedKeys(false)if the built-in list is too broad for your payloads; request.urland network telemetry URLs no longer carry credentials, query strings or fragments. If you rely on query parameters for grouping or search, configure aurlSanitizerthat preserves them.