HIPAA Compliance

HIPAA-Compliant
Error Tracking

Sentry, Datadog and Rollbar are silently capturing PHI in your stack traces. Here's how to fix it — or replace them.

9 min read·Updated Apr 2026

HIPAA-compliant error tracking is non-negotiable for production healthcare apps. But every time Sentry captures an unhandled exception, it packages up the stack trace, the request context, the session data and often the local variable values — then ships it to a third-party server. For most apps, that's fine. For HIPAA-covered applications, it can be an unauthorized disclosure of ePHI.

Why Error Trackers Are a HIPAA Risk

Modern error trackers are designed to capture as much context as possible to help you reproduce bugs. That's exactly the feature that creates the compliance problem. A single captured exception can contain:

Request URL
/patients/12345/records?dob=1990-01-15
Patient ID and date of birth in the URL
Request headers
Authorization: Bearer eyJ...
Session tokens linked to patient accounts
Request body
{"diagnosis": "F32.1", "mrn": "MRN-88421"}
Diagnosis codes and medical record numbers
Stack frame locals
$patient_email = "alice@example.com"
Variable values captured at crash point
Database errors
UNIQUE constraint failed: patients.ssn
Column names revealing data structure and values
Session context
user_id: 882, role: patient, ward: oncology
User identity linked to medical context

This is an unauthorized disclosure of ePHI

Under HIPAA's Security Rule (45 CFR §164.312), sending ePHI to a third-party error tracking service without a Business Associate Agreement constitutes an unauthorized disclosure — regardless of whether you intended to include PHI in the error event. Intent is not a defense.

Which Error Trackers Offer BAAs?

A Business Associate Agreement is the legal minimum for using a managed error tracking service with PHI-containing applications. Not all vendors offer one:

Service BAA Available? Plan Required Notes
Sentry (cloud) ✓ Yes Business or Enterprise Request via support. Also offers self-hosted OSS option.
Sentry OSS (self-hosted) ✓ Not needed Free All data stays on your servers. Strongest HIPAA posture.
Datadog ✓ Yes Enterprise / negotiated BAA covers APM and log management products.
New Relic ✓ Yes Enterprise Full observability platform with BAA for enterprise customers.
Rollbar ✗ No public BAA No published BAA. Do not use for PHI-containing apps without scrubbing all data client-side first.
Bugsnag ✗ No public BAA No published BAA. Same guidance as Rollbar.
Grafana / Loki / Tempo ✓ Self-hosted Free (self-hosted) Open-source stack. All data on your infrastructure.

How to Scrub PHI from Sentry

Even with a BAA, best practice is to scrub PHI before it leaves your application. A BAA is a legal safeguard — scrubbing is technical prevention. Do both.

Python — before_send hook

The before_send hook runs on every event before it is transmitted. Return None to drop the event entirely, or modify the event dict to remove sensitive fields:

import sentry_sdk
import re

def scrub_phi(event, hint):
    """Remove PHI from Sentry events before sending."""

    # Drop events from PHI-heavy endpoints entirely
    request = event.get("request", {})
    url = request.get("url", "")
    if "/patients/" in url or "/medical-records/" in url:
        # Scrub the URL — keep the path structure but remove IDs
        request["url"] = re.sub(r"/patients/\d+", "/patients/[REDACTED]", url)

    # Scrub request body
    if "data" in request:
        request["data"] = "[SCRUBBED]"

    # Scrub query string
    if "query_string" in request:
        request["query_string"] = "[SCRUBBED]"

    # Scrub user context
    if "user" in event:
        user = event["user"]
        if "email" in user:
            user["email"] = "[REDACTED]"
        if "username" in user:
            user.pop("username", None)

    # Scrub extra context
    event.pop("extra", None)

    return event

sentry_sdk.init(
    dsn="https://your-dsn@sentry.io/project-id",
    before_send=scrub_phi,
    # Also configure built-in scrubbing
    send_default_pii=False,  # Critical — disables auto PII collection
)

JavaScript / Node.js — beforeSend hook

import * as Sentry from "@sentry/node";

Sentry.init({
  dsn: "https://your-dsn@sentry.io/project-id",
  sendDefaultPii: false, // Never send default PII

  beforeSend(event) {
    // Scrub request body
    if (event.request) {
      event.request.data = "[SCRUBBED]";
      event.request.query_string = "[SCRUBBED]";
      event.request.cookies = "[SCRUBBED]";

      // Redact PHI patterns from URL
      if (event.request.url) {
        event.request.url = event.request.url
          .replace(/\/patients\/\d+/g, "/patients/[ID]")
          .replace(/mrn=[^&]+/gi, "mrn=[REDACTED]")
          .replace(/dob=[^&]+/gi, "dob=[REDACTED]");
      }
    }

    // Remove user email
    if (event.user) {
      delete event.user.email;
      delete event.user.username;
      delete event.user.ip_address;
    }

    // Remove all extra context (may contain session data)
    delete event.extra;

    return event;
  },
});

Sentry Dashboard — Data Scrubbing Settings

In addition to code-level scrubbing, configure Sentry's server-side data scrubbing as a second layer:

Settings → Security & Privacy → Data Scrubbing
Enable "Use Default Scrubbers" — this automatically redacts credit card numbers, SSNs and passwords from all events.
Add custom scrubbing rules
Add field patterns specific to your app: mrn, patient_id, dob, diagnosis, icd_code, insurance_id. These are scrubbed server-side even if they slip through your before_send hook.
Settings → Security & Privacy → Safe Fields
Whitelist fields that look sensitive but aren't (e.g. a field named "type" that stores event types, not patient types).

How to Scrub PHI from Datadog

Datadog's APM and Log Management products support obfuscation rules. For error tracking specifically, configure the tracer's obfuscation settings:

# Python (dd-trace)
from ddtrace import config, tracer

# Obfuscate query strings matching PHI patterns
config.trace_http_header_tags = {}  # Don't capture headers

# In ddconfig.yaml or environment variables:
# DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP=mrn=[^&]*|dob=[^&]*|ssn=[^&]*

# For logs, configure log scrubbing rules in datadog.yaml:
# logs_config:
#   processing_rules:
#     - type: mask_sequences
#       name: mask_mrn
#       replace_placeholder: "[MRN_REDACTED]"
#       pattern: MRN-\d+
// Node.js (dd-trace)
const tracer = require('dd-trace').init({
  // Obfuscate sensitive query parameters
  queryStringObfuscation: /mrn=[^&]*/gi,

  // Don't capture request bodies on these routes
  blocklist: ['/patients', '/medical-records', '/prescriptions'],
});

The Nuclear Option — Self-Hosted Sentry OSS

If you need the cleanest possible HIPAA posture and have devops capacity, self-hosted Sentry eliminates the third-party risk entirely. All error data stays on infrastructure you control — no BAA required because you're not sending data to a third party at all.

# Install via Docker Compose (official method)
git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
./install.sh

# Or via Helm on Kubernetes
helm repo add sentry https://sentry-kubernetes.github.io/charts
helm install sentry sentry/sentry \
  --set user.email=admin@yourcompany.com \
  --set user.password=yourpassword

Self-hosted Sentry gives you the same UI and SDK compatibility as Sentry cloud. The trade-off is infrastructure management — you're responsible for backups, updates and availability.

HIPAA Error Tracking Compliance Checklist

BAA signed with your error tracking vendor
Or use self-hosted/open-source that requires no BAA.
sendDefaultPii: false in Sentry SDK
Disables automatic collection of IP addresses, usernames and cookies.
before_send hook implemented
Scrubs request body, query string, user email and extra context before transmission.
Dashboard data scrubbing rules configured
Server-side second layer for fields that slip through the SDK hook.
PHI-heavy endpoints identified and handled
Either drop events from those routes or scrub aggressively.
Retention period configured
HIPAA requires documented retention limits. Set event retention in your error tracker settings.
Access controls audited
Only staff with legitimate need should have access to error tracking dashboards.
Documented in HIPAA risk assessment
Your risk assessment must include error tracking as a data flow. Document mitigations.

Test with synthetic PHI before going live

After configuring scrubbing, trigger test errors using fake patient data (fabricated names, MRNs and diagnosis codes) and verify the captured events contain no real-looking PHI. Check request bodies, URLs, stack frame locals and user context fields.

Before Sharing Error Logs — Sanitize First

Even with error tracking properly configured, you may sometimes need to share raw logs or stack traces for debugging — with a colleague, a vendor or an AI assistant. Always sanitize first.

Sanitize Logs Before Sharing

Strip emails, IPs, API keys and PHI patterns from logs in seconds. 100% client-side — nothing uploaded.

Open Log Sanitizer — Free →

FAQ

Does Sentry offer a HIPAA BAA? +

Yes. Sentry offers a BAA on Business and Enterprise plans. Contact their support team to request it. Alternatively, self-hosted Sentry OSS requires no BAA since all data remains on your own infrastructure.

Can PHI end up in error tracking events? +

Very easily. Stack frames capture local variable values at crash points. Request context includes the full URL (which may contain patient IDs), query parameters, and headers. Session context includes user identity. Any of these can contain PHI without the developer explicitly including it.

What is the safest error tracking setup for a HIPAA app? +

Self-hosted Sentry OSS — all data stays on infrastructure you control, no third-party BAA required. For managed services, Sentry Business or Datadog with a signed BAA and a before_send scrubbing hook configured is the next best option.

Is a BAA enough, or do I also need to scrub PHI? +

A BAA is the legal minimum — it creates a contractual obligation for the vendor to protect PHI. But it doesn't prevent PHI from being captured and stored. Technical scrubbing is the preventive layer. Best practice is both: BAA for legal coverage, scrubbing to minimize the PHI that ever reaches the vendor's servers.

Related