> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ontime.hosai.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Terminal troubleshooting

> Offline devices, missing punches, wrong timestamps — the distinct signatures of each cause.

Terminal problems have distinct signatures. Reading the right one saves a lot of time.

## Punches are not appearing

This is the common report, and it has four causes with completely different fixes. Work through them in this order.

<Steps>
  <Step title="Is the terminal user mapped?">
    **By far the most likely.** A punch whose terminal user ID does not resolve to an employee is **parked** — held, not lost.

    Check **Attendance → Devices → Unclaimed users** for IDs with no confirmed employee. Mapping one replays every punch waiting behind it automatically.

    <Note>
      Also parks: an **ambiguous** suffix match, where two employee codes both end in the terminal's number. OnTime refuses to guess.
    </Note>
  </Step>

  <Step title="Is the device registered?">
    An unregistered serial appears in the unclaimed list. Its punches are not attributed to your organization until you register it.
  </Step>

  <Step title="Is the device online?">
    A device silent for 5 minutes is marked `Offline`. If it is genuinely disconnected, the punches are **in its flash**, not lost — they arrive when it reconnects.
  </Step>

  <Step title="Is the connector reaching OnTime?">
    Check the connector's logs for acknowledgement lines. No acknowledgements means it is not getting success responses from OnTime — see the next section.
  </Step>
</Steps>

## The connector is not acknowledging

| Symptom                          | Cause                                                                | Fix                                  |
| -------------------------------- | -------------------------------------------------------------------- | ------------------------------------ |
| OnTime returns `401`             | `CONNECTOR_SECRET` does not match the backend's.                     | Set them identically on both sides.  |
| OnTime returns `503`             | The backend has no connector secret configured — the feature is off. | Provision one.                       |
| Connection refused or timing out | `BACKEND_URL` wrong, or no outbound HTTPS from the connector host.   | Check the URL and the host's egress. |

<Warning>
  **A wrong secret is silent from the device's point of view.** The terminal keeps retrying every 60 seconds and its queue backs up, but nothing surfaces in OnTime — because nothing reaches OnTime. Nothing is lost, but nothing arrives.

  If devices look healthy and OnTime looks empty, check the secret first.
</Warning>

## A device shows Offline

Liveness comes from keepalive messages only. Silent for **5 minutes** means `Offline`; the next keepalive flips it back.

<AccordionGroup>
  <Accordion title="It flickers offline and back" icon="activity">
    An unstable network. Annoying, not harmful — punches sit in flash and deliver on reconnection.
  </Accordion>

  <Accordion title="It has been offline since a specific time" icon="power-off">
    Power or network at the device end, or the connector host is down. Check the connector first — if every device went offline at once, it is the connector, not the devices.
  </Accordion>

  <Accordion title="It shows offline but punches are arriving" icon="triangle-alert">
    Unlikely, since delivery implies connectivity. Check whether the device is registered as a kiosk — kiosk-kind devices are exempt from the offline watchdog.
  </Accordion>
</AccordionGroup>

## Punches land at the wrong time

<Warning>
  **Almost always `DEVICE_TZ_OFFSET`.** F500 terminals report wall-clock time with no timezone, and the connector stamps every message with this configured offset. If it does not match what the terminals are set to, every punch is shifted.

  The damage is not cosmetic: shifted punches change late minutes, overtime bands, and which day a punch belongs to near midnight.
</Warning>

<Steps>
  <Step title="Check the terminal's own clock and timezone">
    In its admin menu.
  </Step>

  <Step title="Check DEVICE_TZ_OFFSET matches it">
    Default is `+05:30`.
  </Step>

  <Step title="If your sites span timezones, run one connector per zone">
    There is no per-device offset — the offset is connector-wide.
  </Step>
</Steps>

Punches already recorded at the wrong time need correcting as attendance — see [Manual punches and overrides](/help/attendance/manual-punches-and-overrides).

## Punches landed on the wrong person

A mapping was wrong, or a suffix match resolved to someone unintended.

<Steps>
  <Step title="Fix the mapping first">
    So it stops happening.
  </Step>

  <Step title="Then correct the attendance">
    <Warning>
      **Deleting a mapping does not un-apply punches already applied.** They are real events on real day records. Correct them with day overrides on both employees — the one who was wrongly credited and the one who was missed.
    </Warning>
  </Step>
</Steps>

<Tip>
  This is the argument for explicit mappings over the numeric-suffix convention. Suffix matching works until two codes collide, and by then it has already misattributed a day.
</Tip>

## A punch appears twice

<Note>
  Deduplication is on `(device, transaction ID, log time)` together, and it is reliable. If somebody appears twice from one terminal, they punched twice.

  A punch from **two different sources** — a terminal punch and a mobile punch for the same arrival — is a different thing, and OnTime flags it as a conflict on the live board so you can decide which is real.
</Note>

## A device does not appear at all

<AccordionGroup>
  <Accordion title="It never connected" icon="cable">
    Check the device's LogServer IP and port, and that the connector's port is reachable from the device's subnet. A firewall between them is the usual cause.
  </Accordion>

  <Accordion title="The connector is not running" icon="server-off">
    Check the container. It should be running with a restart policy.
  </Accordion>

  <Accordion title="It connected but the messages are unparseable" icon="file-x">
    Visible in the connector's logs. Unparseable bytes are deliberately **not** acknowledged, so a device sending malformed data will retry indefinitely. Usually a firmware or model mismatch — the connector targets F500-class LogServer devices.
  </Accordion>
</AccordionGroup>

## Verifying a fix

Do not wait for a real punch. Replay a session with the fake device — it exercises the whole path in seconds. See [Test with a fake device](/terminals/test-with-fake-device).
