Troubleshooting
Common issues and solutions for JavaScript cron monitoring setup.
Common issues and solutions for JavaScript cron monitoring setup.
Setup Issues
Check-ins aren't appearing in Sentry
Possible causes:
- Monitor doesn't exist - Make sure you've created the monitor in Sentry first (except for automatic instrumentation)
- Wrong monitor slug - Verify the monitor slug matches exactly (case-sensitive)
- Network issues - Check if your server can reach Sentry's ingest domain
- SDK not initialized - Ensure Sentry SDK is properly configured with valid DSN
Solutions:
// Verify your Sentry configuration
import * as Sentry from "@sentry/node";
Sentry.init({
dsn: "YOUR_DSN", // Make sure this is correct
debug: true, // Enable for troubleshooting
});
// Test with a simple check-in
Sentry.captureCheckIn({
monitorSlug: "your-monitor-slug",
status: "ok",
});
Getting 404 errors for check-ins
Possible causes:
- Incorrect ingest domain - Using wrong Sentry domain
- Wrong project ID - Check your project settings
- Invalid monitor slug - Monitor doesn't exist or name is wrong
Solutions:
- Verify your ingest domain from Sentry settings
- Check project ID in your Sentry dashboard URL
- Ensure monitor was created successfully in Sentry
Automatic instrumentation not working
Requirements check:
- SDK Version: node-cron requires
7.92.0+
, node-schedule requires7.93.0+
- Proper Import: Use the instrumented version, not the original library
- Monitor Name: Provide a
name
parameter for the job
Solution:
// Check SDK version
console.log(require("@sentry/node/package.json").version);
// Correct usage
import * as Sentry from "@sentry/node";
import cron from "node-cron";
const cronWithCheckIn = Sentry.cron.instrumentNodeCron(cron);
// Must include name parameter
cronWithCheckIn.schedule("0 * * * *", myJob, {
name: "my-job-name", // Required!
});
Monitor Behavior Issues
Jobs showing as missed when they ran successfully
Possible causes:
- Schedule mismatch - Sentry schedule doesn't match when job actually runs
- Timezone issues - Server timezone differs from monitor timezone
- Late check-ins - Notification happens after the grace period
- Clock drift - Server time is out of sync
Solutions:
- Verify cron schedule matches exactly:
crontab -l
vs Sentry monitor - Check server timezone:
date
and compare with monitor timezone - Send check-ins immediately after job completion
- Sync server time with NTP
Jobs running but runtime not tracked
For runtime tracking, you need:
- Start AND end check-ins (not just end)
- Use
in_progress
status at job start - Use
ok
orerror
status at job end
// Correct runtime tracking
const checkInId = Sentry.captureCheckIn({
monitorSlug: "my-job",
status: "in_progress", // Start tracking
});
try {
await runJob();
Sentry.captureCheckIn({
checkInId,
monitorSlug: "my-job",
status: "ok", // End tracking
});
} catch (error) {
Sentry.captureCheckIn({
checkInId,
monitorSlug: "my-job",
status: "error",
});
}
Not receiving alerts when monitors fail
Check these settings:
- Alert Rules: Navigate to Alerts → Create Alert → Issues
- Filter Setup: Use
monitor.slug
equals your monitor slug - Notification Settings: Verify email/Slack integration
- Issue Creation: Check if issues are being created for failures
Example alert setup:
- Alert Type: Issues
- Filter:
The event's tags match monitor.slug equals my-monitor-slug
- Conditions: When an issue is first seen or seen more than X times
Error Tracking Issues
Runtime errors not appearing in monitor details
To link errors to monitors:
- Use SDK methods: Errors captured via SDK are automatically linked
- Check error timing: Errors must occur during job execution
- Verify error capture: Ensure
Sentry.captureException()
is called
Sentry.withMonitor("my-job", async () => {
try {
await riskyOperation();
} catch (error) {
// This error will be linked to the monitor
Sentry.captureException(error);
throw error; // Re-throw to mark job as failed
}
});
Too many errors being captured
To reduce noise:
- Filter by error level: Only capture important errors
- Use sampling: Reduce error reporting volume
- Scope errors properly: Use
withScope
for context
Sentry.withScope((scope) => {
scope.setTag("job_context", "data_processing");
scope.setLevel("warning"); // Only warnings and above
if (isCriticalError(error)) {
Sentry.captureException(error);
}
});
Environment-Specific Issues
Development vs Production differences
Common differences:
- Schedule frequency: Dev jobs often run more frequently
- Timeout settings: Dev environments may be slower
- Error tolerance: Production should be less tolerant
Solution - Environment configs:
const configs = {
production: {
checkinMargin: 5,
maxRuntime: 30,
failureIssueThreshold: 1,
},
development: {
checkinMargin: 15,
maxRuntime: 120,
failureIssueThreshold: 3,
},
};
const config = configs[process.env.NODE_ENV] || configs.production;
Serverless function timeouts
For AWS Lambda, Vercel, etc.:
- Platform limits: Respect function timeout limits
- Cold starts: Account for initialization time
- Concurrency: Handle multiple executions properly
// AWS Lambda example
export const handler = Sentry.AWSLambda.wrapHandler(async (event) => {
return Sentry.withMonitor(
"lambda-job",
async () => {
// Your job logic here
await processEvent(event);
},
{
maxRuntime: 5, // Much shorter for Lambda
checkinMargin: 2,
},
);
});
Debugging Tips
Enable debug logging
// Enable Sentry debug mode
Sentry.init({
dsn: "YOUR_DSN",
debug: true, // Shows Sentry internal logs
});
// Add custom logging
console.log("Job starting...");
const checkInId = Sentry.captureCheckIn({
monitorSlug: "debug-job",
status: "in_progress",
});
console.log("Check-in ID:", checkInId);
Test monitor setup manually
// Quick test script
import * as Sentry from "@sentry/node";
Sentry.init({ dsn: "YOUR_DSN" });
async function testMonitor() {
console.log("Testing monitor...");
const checkInId = Sentry.captureCheckIn({
monitorSlug: "test-monitor",
status: "in_progress",
});
// Simulate work
await new Promise((resolve) => setTimeout(resolve, 1000));
Sentry.captureCheckIn({
checkInId,
monitorSlug: "test-monitor",
status: "ok",
});
console.log("Test complete - check Sentry dashboard");
}
testMonitor();
General Information
What is the check-in data retention policy?
Check-in data is retained for 90 days. After this period, check-in history is automatically removed.
Do you support six-field crontab expressions?
Currently, Sentry only supports five-field crontab expressions (minute, hour, day, month, weekday). Six-field expressions with seconds are not supported.
Supported: 0 */2 * * *
(every 2 hours)
Not supported: 0 0 */2 * * *
(every 2 hours with seconds field)
Can I monitor jobs that run longer than their interval?
Yes! Use overlapping job handling with unique check-in IDs:
import { v4 as uuidv4 } from "uuid";
const checkInId = uuidv4(); // Unique ID for this execution
Sentry.captureCheckIn({
checkInId,
monitorSlug: "long-job",
status: "in_progress",
});
// Long-running job logic...
Sentry.captureCheckIn({
checkInId,
monitorSlug: "long-job",
status: "ok",
});
Getting Help
If you're still experiencing issues:
- Check Sentry Status: Visit status.sentry.io
- Review Documentation: Return to the main cron documentation
- Community Support: Ask on Discord or GitHub Discussions
- Contact Support: Use the in-app support chat for technical issues
Setup Method Troubleshooting
Having trouble with your specific setup method? Check the troubleshooting sections in:
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").