Epure
SDK

Sentry envelope keep/drop verify on Epure (202 empty Issues)

sentry envelope keep drop verify

Epure keeps event items, discards transaction, skips replay/profile/session. Verify 202 then Issues; store vs envelope bisect; CORS and PUBLIC_URL rows.

On this pageShow
  1. Keep vs drop items
  2. 202 but empty Issues
  3. Store vs envelope
  4. Bisect order
  5. CORS and PUBLIC_URL
  6. Caps and spike valve
  7. Who should use what
  8. Limitations
  9. Questions

Epure is exception-only ingest: envelope event items are persisted; transaction items are discarded; replay_*, profile*, session, attachment, and check_in are skipped. No event item returns 400 invalid_envelope. Success is 202 Accepted plus { "id" }, then an unresolved Issues row. Empty Issues after 202 usually means env filter, wrong project, or worker flush.

You already run official @sentry/browser or @sentry/node against a two-container self-host (Rust binary + PostgreSQL 16) and need to know which envelope items become Issues. Full Sentry self-host with Relay/Kafka workers that persist tracing and replay is the undesired alternative for this path. This how-to is the verify path: keep/drop honesty, then store -> envelope -> SDK -> CORS bisect.

Unique wedge: Epure exception-only item handling from the Envelope docs table. event persisted; transaction discarded; replay_* / profile* / session / attachment / check_in skipped. Bias disclosed: Epure first-party docs are the source of truth for Epure behavior; Sentry envelope docs describe a fuller item surface.

Primary how-to: Envelope. Acceptance: Verify. Pin/init: Quickstart. Host shape: Installation. Symptom matrix: Troubleshooting. Env: Configuration. Sibling context: Sentry SDK compatible, Spike valve fingerprint flood, Two-container error tracking, Epure vs Sentry.

Keep vs drop items

Epure parses, queues, and persists envelope event items only. transaction items are discarded because the product is exception-only. attachment, session, replay_*, profile*, check_in, and other item types are skipped. An envelope with no event item returns 400 invalid_envelope.

Envelope item handling (Envelope docs)

event

Behavior (Envelope)
Parsed, queued, persisted

transaction

Behavior (Envelope)
Discarded (exception-only product)

attachment, session, replay_*, profile*, check_in, other

Behavior (Envelope)
Skipped
DimensionBehavior (Envelope)
eventParsed, queued, persisted
transactionDiscarded (exception-only product)
attachment, session, replay_*, profile*, check_in, otherSkipped

Ingest success stays 202 { "id" } when non-event items are present but skipped or discarded. Do not invent per-item HTTP status codes beyond the Envelope table and response section.

202 but empty Issues

A successful ingest returns 202 Accepted plus { "id" } before the Issues row appears. If Issues stays empty, wait about 1 second (Verify) or about 500 ms (Troubleshooting), match the environment filter to your SDK tag (often local), confirm the project that owns the DSN, and check docker compose logs epure. Empty feed copy can read 0 UNRESOLVED EXCEPTIONS when nothing is unresolved.

202 but empty Issues: symptom to fix (Verify / Troubleshooting)

202 but Issues empty

Fix (Verify / Troubleshooting)
Wait ~1s / ~500 ms; filter `local`; correct project; `docker compose logs epure`

Env chip mismatch

Fix (Verify / Troubleshooting)
Match environment filter to `Sentry.init` (`local` / `production` / all)

Wrong project

Fix (Verify / Troubleshooting)
Open host or `EPURE_PUBLIC_URL`; select project that owns DSN

Flood still 202, Issues quiet

Fix (Verify / Troubleshooting)
Spike valve - send slower unique exception or wait; not a failed verify

Cookie / login loop on HTTP

Fix (Verify / Troubleshooting)
`EPURE_SESSION_SECURE=0` for local HTTP (session path, not DSN ingest)
DimensionFix (Verify / Troubleshooting)
202 but Issues emptyWait ~1s / ~500 ms; filter `local`; correct project; `docker compose logs epure`
Env chip mismatchMatch environment filter to `Sentry.init` (`local` / `production` / all)
Wrong projectOpen host or `EPURE_PUBLIC_URL`; select project that owns DSN
Flood still 202, Issues quietSpike valve - send slower unique exception or wait; not a failed verify
Cookie / login loop on HTTP`EPURE_SESSION_SECURE=0` for local HTTP (session path, not DSN ingest)

Store vs envelope

POST /api/{project_id}/envelope/ takes application/x-sentry-envelope (newline-delimited, <= 2 MB). POST /api/{project_id}/store/ takes JSON (or gzip/zlib via Content-Encoding) <= 2 MB. Both use DSN auth and return the same 202 { "id" } success shape. Malformed envelope with no event -> 400 invalid_envelope; malformed store -> 400 invalid_store. Over 2 MB -> 413 payload_too_large on both.

Store vs envelope (Envelope / Authentication / Verify)

Path

Envelope
`POST /api/{project_id}/envelope/`
Store (legacy)
`POST /api/{project_id}/store/`

Content-Type

Envelope
`application/x-sentry-envelope`
Store (legacy)
`application/json` (or gzip/zlib)

Body

Envelope
Newline-delimited <= 2 MB
Store (legacy)
JSON event <= 2 MB

Auth

Envelope
DSN
Store (legacy)
Same DSN

Success

Envelope
202 + `{ "id" }`
Store (legacy)
Same 202 + `{ "id" }`

Malformed

Envelope
400 `invalid_envelope`
Store (legacy)
400 `invalid_store`

Session cookie

Envelope
Ignored
Store (legacy)
Ignored
DimensionEnvelopeStore (legacy)
Path`POST /api/{project_id}/envelope/``POST /api/{project_id}/store/`
Content-Type`application/x-sentry-envelope``application/json` (or gzip/zlib)
BodyNewline-delimited <= 2 MBJSON event <= 2 MB
AuthDSNSame DSN
Success202 + `{ "id" }`Same 202 + `{ "id" }`
Malformed400 `invalid_envelope`400 `invalid_store`
Session cookieIgnoredIgnored

Bisect order

Bisect documented order: (1) store JSON curl (smallest wire path), (2) envelope fixture curl, (3) SDK captureException, (4) if the browser fails CORS, OPTIONS curl plus EPURE_CORS_ORIGINS. Session cookies on envelope or store do nothing; DSN belongs on ingest, not on /api/v1/*.

Baseline store curl (Verify / Envelope seed defaults):

curl -sS -D - -o /tmp/epure-ingest.json -X POST "http://localhost:8080/api/550e8400-e29b-41d4-a716-446655440000/store/" -H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=a1b2c3d4e5f6g7h8i9j0, sentry_secret=supersecretdevkey" -H "Content-Type: application/json" -d '{"platform":"javascript","exception":{"values":[{"type":"Error","value":"Epure try-it"}]}}'

Expected (Verify success table / Envelope): HTTP/1.1 202 Accepted + { "id": "<uuid>" }, then an unresolved issue for that exception type.

Envelope fixture curl (from repo root after seed-dev):

curl -sS -D - -o /tmp/epure-envelope.json -X POST "http://localhost:8080/api/550e8400-e29b-41d4-a716-446655440000/envelope/" -H "X-Sentry-Auth: Sentry sentry_version=7, sentry_key=a1b2c3d4e5f6g7h8i9j0, sentry_secret=supersecretdevkey" -H "Content-Type: application/x-sentry-envelope" --data-binary @fixtures/sentry/browser/envelope.txt

Expected (Envelope): HTTP/1.1 202 Accepted + { "id": "..." }.

SDK one-liner (Verify): Sentry.captureException(new Error("Epure verify test"));

When showing install lines, pin @sentry/browser@7.120.0 or @sentry/node@7.120.0 (Quickstart).

CORS and PUBLIC_URL

Browser CORS failures mean the origin is not in EPURE_CORS_ORIGINS; recreate the epure service after changing it. OPTIONS on the envelope path should return 200 or 204 with Access-Control-Allow-Origin. Set EPURE_PUBLIC_URL for ngrok, custom host, or production HTTPS; for local plain HTTP login loops set EPURE_SESSION_SECURE=0 (session path, not DSN ingest).

OPTIONS preflight (Troubleshooting):

curl -sS -D - -o /dev/null -X OPTIONS "http://localhost:8080/api/${PROJECT_ID}/envelope/" -H "Origin: http://localhost:5173" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Sentry-Auth, Content-Type"

Production-shaped vars (Configuration example): EPURE_PORT=8080, EPURE_PUBLIC_URL=https://errors.example.com, EPURE_CORS_ORIGINS=https://app.example.com, plus POSTGRES_PASSWORD, EPURE_INGEST_PASSWORD, and EPURE_APP_PASSWORD set to non-default secrets.

Caps and spike valve

Default project ingest cap is 5000 events per hour; over that returns 403 ingest_cap_exceeded before enqueue. Flooding the same fingerprint (~100+/min) still returns 202 and bumps counters while duplicate bodies may drop: that is the spike valve, not a failed verify. For flood economics and bill-shock framing, read Spike valve fingerprint flood; this article does not remake that angle.

Other documented ingest failures (Verify / Envelope): 401 invalid_dsn; 403 dsn_revoked; 403 project_mismatch; 503 queue_unavailable.

Who should use what

Use this guide if you already point official Sentry SDKs at a two-container Epure host and need to know which envelope items become Issues. Read sibling posts for DSN-swap scoreboard, spike-valve flood economics, or two-container host shape. Stay on Sentry Cloud if session replay or APM is the daily debug loop.

Use this guide if

  • You already point official Sentry SDKs at a 2-container Epure host and need keep/drop honesty for envelope items.
  • You see 202 Accepted but empty Issues and need the env-chip / project / worker checklist.
  • You want the store -> envelope -> SDK -> CORS bisect order from first-party docs.

Read something else if

Limitations

Epure is not 100% Sentry compatible. Session replay, APM tracing, and profiling are not Epure features (transaction discarded; replay_* / profile* skipped). Redis, Kafka, and ClickHouse are not default Epure services. Stack is two Compose services: Rust binary + PostgreSQL 16 (postgres:16-alpine). Cloud is not live.

Negative scope (must-read):

  • Epure is not 100% Sentry compatible.
  • Session replay, APM tracing, and profiling are not Epure features.
  • Symbolicator is not an Epure component.
  • Redis, Kafka, and ClickHouse are not default Epure services for this path.
  • Cloud is not live.
  • This article does not quote fixture byte contents, idle RAM figures, rustc semver, or image digests.
  • Do not remake the spike-valve bill-shock ArticlePost from this pack.

Deep links: Envelope | Verify | Quickstart | Installation | Troubleshooting | Configuration.

FAQ

Questions

What envelope item types does Epure keep?
Epure parses, queues, and persists event items. transaction items are discarded. attachment, session, replay_*, profile*, check_in, and other types are skipped. An envelope with no event item returns 400 invalid_envelope.
Why do I get HTTP 202 but no Issues row?
Wrong project, environment filter mismatch, or the ingest worker still flushing. Wait about 1 second (Verify) or about 500 ms (Troubleshooting), select the project that owns the DSN, match the env chip to Sentry.init (local / production / all), and check docker compose logs epure.
How do store and envelope differ on Epure?
Both authenticate with the project DSN and return 202 Accepted plus { "id" }. Envelope uses Content-Type application/x-sentry-envelope with a newline-delimited body <= 2 MB. Store uses JSON (or gzip/zlib) <= 2 MB. Malformed cases return 400 invalid_envelope or 400 invalid_store.
How should I bisect a failed verify?
Run store JSON curl first, then the envelope fixture, then SDK Sentry.captureException(new Error("Epure verify test")). If the browser fails CORS, run OPTIONS and set EPURE_CORS_ORIGINS to your real frontend origins.
Does a session cookie authenticate ingest?
No. Session cookies on envelope or store do nothing. Ingest uses DSN (X-Sentry-Auth or query keys). DSN headers on /api/v1/* dashboard APIs return 401.
Is a spike-valve flood a failed verify?
No. Flooding the same fingerprint at about 100+ per minute still returns 202 and bumps counters; duplicate bodies may drop. That is the spike valve, not a failed verify. Hourly cap default 5000 returns 403 ingest_cap_exceeded instead.
Is Epure 100% Sentry compatible for envelopes?
No. Epure is exception-only: it keeps event items for Issues and discards or skips tracing, replay, profile, session, attachment, and check-in item classes. It is not full Sentry parity.