What React Native libraries do you use?
Expo Router, Expo (mobile only)
Are you using sentry.io or on-premise?
sentry.io (SaS)
Are you using any other error monitoring solution alongside Sentry?
Yes
Other Error Monitoring Solution Name
Expo Observe
@sentry/react-native SDK Version
8.19.0 and test 8.20.0
How does your development environment look like?
@sentry/react-native 8.19.0 (observed) and 8.20.0 (confirmed still affected)
@sentry/core 10.65.0 → 10.67.0 (both affected; source identical)
- React Native 0.86.0 (Hermes), Expo SDK 57, React 19.2.3
- Device: iPhone, iOS 26.5.2 (device clock correct / set to automatic)
Sentry.init()
Sentry.init({
dsn: 'https://...@sentry.io/...'
sendDefaultPii: true,
// Enable Logs
enableLogs: true,
beforeSendLog(log) {
return log;
},
// Debug
debug: true, //__DEV__, // true in dev builds
// Configure Session Replay
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1,
integrations: [
Sentry.consoleLoggingIntegration({
levels: ['debug', 'info', 'log', 'warn', 'error'],
}),
Sentry.mobileReplayIntegration({}),
Sentry.feedbackIntegration({
styles: {
submitButton: {
backgroundColor: '#6E4EA1',
borderRadius: 5,
},
},
}),
],
});
I know some options are not supported / useless in sentry/react-native (like Sentry.consoleLoggingIntegration) I was just testing all possible options to try to get the logs to work until I finally realized the ~4 days lag
Steps to Reproduce
Summary
Sentry.logger.* structured logs arrive in Sentry with a timestamp that is wrong by a large, constant offset (in our case ≈ 4.25 days, ≈ the device's uptime), while error/event timestamps are correct. The device's wall clock is correct — a Date.now() value we attach to each log as an attribute is spot-on; only the SDK-assigned log timestamp is off.
This is not an ingestion/Relay issue: the affected logs have no sentry._meta.fields.timestamp substitution, i.e. Relay accepted the SDK's timestamp verbatim. The wrong value is computed in the SDK.
Root cause
Logs stamp their timestamp with timestampInSeconds():
packages/core/src/logs/internal.ts
const timestamp = timestampInSeconds();
timestampInSeconds() trusts the Performance API unconditionally — no sanity check:
packages/core/src/utils/time.ts
function createUnixTimestampInSecondsFunc(): () => number {
const { performance } = GLOBAL_OBJ as ...;
if (!performance?.now || !performance.timeOrigin) {
return dateTimestampInSeconds;
}
const timeOrigin = performance.timeOrigin;
return () => {
return (timeOrigin + withRandomSafeContext(() => performance.now())) / ONE_SECOND_IN_MS;
};
}
On React Native / Hermes, performance.timeOrigin + performance.now() is not reliably wall-clock-anchored, so timeOrigin + now() is off by a constant. Notably, this same file already has a reliability check — getBrowserTimeOrigin() compares timeOrigin + performance.now() against Date.now() with a 5-minute threshold and falls back — but that guard is only used by browserPerformanceTimeOrigin() (tracing), not by timestampInSeconds(), and the log path calls timestampInSeconds() directly.
Errors are unaffected because event timestamps go through dateTimestampInSeconds() (= Date.now()).
Steps to reproduce
On an affected RN device (where the performance clock is skewed vs the wall clock):
console.log('Date.now() =', Date.now());
console.log('performance.timeOrigin =', performance.timeOrigin);
console.log('performance.now() =', performance.now());
// This is exactly what @sentry/core stamps onto a log:
console.log('SDK log clock =', performance.timeOrigin + performance.now());
Sentry.logger.info('clock check', { deviceNow: Date.now() });
Observe in the Logs Explorer that the log's timestamp equals performance.timeOrigin + performance.now() and differs from the deviceNow attribute (and from reality) by a constant offset.
Expected Result
Log timestamp should match Date.now() / real wall-clock time, the same as error events.
Actual Result
Log timestamp is performance.timeOrigin + performance.now(), wrong by a constant offset (≈ device uptime). Real data from one 2.3-minute session (38 logs):
|
value |
as UTC |
SDK log timestamp |
1784453353.186 |
2026-07-19T09:29:13.186Z (wrong) |
our Date.now() attribute |
1784820130576 |
2026-07-23T15:22:10.576Z (correct) |
Offset ≈ 366,777 s (~4.25 days), constant across all 38 logs (drift ~0.1 s over the session) — the signature of a monotonic clock anchored to a bad origin, not a wall-clock error.
What React Native libraries do you use?
Expo Router, Expo (mobile only)
Are you using sentry.io or on-premise?
sentry.io (SaS)
Are you using any other error monitoring solution alongside Sentry?
Yes
Other Error Monitoring Solution Name
Expo Observe
@sentry/react-native SDK Version
8.19.0 and test 8.20.0
How does your development environment look like?
@sentry/react-native8.19.0 (observed) and 8.20.0 (confirmed still affected)@sentry/core10.65.0 → 10.67.0 (both affected; source identical)Sentry.init()
I know some options are not supported / useless in sentry/react-native (like Sentry.consoleLoggingIntegration) I was just testing all possible options to try to get the logs to work until I finally realized the ~4 days lag
Steps to Reproduce
Summary
Sentry.logger.*structured logs arrive in Sentry with a timestamp that is wrong by a large, constant offset (in our case ≈ 4.25 days, ≈ the device's uptime), while error/event timestamps are correct. The device's wall clock is correct — aDate.now()value we attach to each log as an attribute is spot-on; only the SDK-assigned logtimestampis off.This is not an ingestion/Relay issue: the affected logs have no
sentry._meta.fields.timestampsubstitution, i.e. Relay accepted the SDK's timestamp verbatim. The wrong value is computed in the SDK.Root cause
Logs stamp their timestamp with
timestampInSeconds():packages/core/src/logs/internal.tstimestampInSeconds()trusts the Performance API unconditionally — no sanity check:packages/core/src/utils/time.tsOn React Native / Hermes,
performance.timeOrigin+performance.now()is not reliably wall-clock-anchored, sotimeOrigin + now()is off by a constant. Notably, this same file already has a reliability check —getBrowserTimeOrigin()comparestimeOrigin + performance.now()againstDate.now()with a 5-minute threshold and falls back — but that guard is only used bybrowserPerformanceTimeOrigin()(tracing), not bytimestampInSeconds(), and the log path callstimestampInSeconds()directly.Errors are unaffected because event timestamps go through
dateTimestampInSeconds()(=Date.now()).Steps to reproduce
On an affected RN device (where the performance clock is skewed vs the wall clock):
Observe in the Logs Explorer that the log's
timestampequalsperformance.timeOrigin + performance.now()and differs from thedeviceNowattribute (and from reality) by a constant offset.Expected Result
Log
timestampshould matchDate.now()/ real wall-clock time, the same as error events.Actual Result
Log
timestampisperformance.timeOrigin + performance.now(), wrong by a constant offset (≈ device uptime). Real data from one 2.3-minute session (38 logs):timestamp1784453353.186Date.now()attribute1784820130576Offset ≈ 366,777 s (~4.25 days), constant across all 38 logs (drift ~0.1 s over the session) — the signature of a monotonic clock anchored to a bad origin, not a wall-clock error.