Skip to content

Companion pairing fails silently on tvOS 26.3 (Apple TV 4K Gen 3) — PIN never displayed #2837

@paolocamerin

Description

@paolocamerin

Describe the bug

Environment

  • pyatv version: 0.17.0
  • Python: 3.9
  • OS: macOS (also reproduced targeting a Raspberry Pi)
  • Apple TV: Apple TV 4K (Gen 3), tvOS 26.3 (AppleTV14,1)

What happens

Running atvremote --protocol companion --address 192.168.X.X --id <device-uuid> pair reaches the PIN entry step but the Apple TV never displays a PIN on screen.
The cryptographic handshake completes (SRP pub key and salt exchanged), pyatv prints "Enter PIN on screen:", but no dialog appears on the TV.

Error log

This log has redacted information

2026-03-22 HH:MM:SS DEBUG [pyatv.scripts]: Running with pyatv 0.17.0                                                 
  2026-03-22 HH:MM:SS DEBUG [pyatv.storage.file_storage]: Loading settings from ~/.pyatv.conf                          
  2026-03-22 HH:MM:SS DEBUG [pyatv.support.net]: Binding on *:5353                                                     
  2026-03-22 HH:MM:SS DEBUG [pyatv.support.net]: Binding on 127.0.0.1:0                                                
  2026-03-22 HH:MM:SS DEBUG [pyatv.support.net]: Binding on 192.168.x.x:0                                              
  2026-03-22 HH:MM:SS DEBUG [pyatv.core.scan]: Auto-discovered Living room at 192.168.x.x:49153 via Protocol.Companion 
  ({'rpmac': '2', 'rphn': '[redacted]', 'rpfl': '0x3678A', 'rpha': '[redacted]', 'rpmd': 'AppleTV14,1', 'rpvr':        
  '715.2', 'rpad': '[redacted]', 'rphi': '[redacted]', 'rpba': '[redacted]', 'rpmrtid': '[redacted-uuid]'})
  2026-03-22 HH:MM:SS DEBUG [pyatv.core.scan]: Auto-discovered Living room at 192.168.x.x:7000 via Protocol.AirPlay    
  ({'acl': '0', 'btaddr': '[redacted]', 'deviceid': '[redacted]', 'fex': '1d9/St5/Fzw4oY58', 'features':               
  '0x4A7FDFD5,0x3C177FDE', 'flags': '0x1004c4', 'gid': '[redacted-uuid]', 'igl': '1', 'gcgl': '1', 'model':
  'AppleTV14,1', 'protovers': '1.1', 'pi': '[redacted-uuid]', 'psi': '[redacted-uuid]', 'pk': '[redacted]', 'srcvers': 
  '935.7.1', 'osvers': '26.3', 'vv': '1'})                  
  2026-03-22 HH:MM:SS DEBUG [pyatv.core.scan]: Auto-discovered [redacted]@Living room at 192.168.x.x:7000 via
  Protocol.RAOP ({'cn': '0,1,2,3', 'da': 'true', 'et': '0,3,5', 'ft': '0x4A7FDFD5,0x3C177FDE', 'sf': '0x1004c4', 'md': 
  '0,1,2', 'am': 'AppleTV14,1', 'pk': '[redacted]', 'tp': 'UDP', 'vn': '65537', 'vs': '935.7.1', 'ov': '26.3', 'vv':
  '1'})                                                                                                                
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.pairing]: Start pairing Companion
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.connection]: Connected to companion device 192.168.x.x:49153    
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.protocol]: Companion credentials: None                          
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.protocol]: Exchange OPACK: {'_pd': b'\x00\x01\x00\x06\x01\x01', 
  '_pwTy': 1}                                                                                                          
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.protocol]: Send OPACK: {'_pd': b'\x00\x01\x00\x06\x01\x01',     
  '_pwTy': 1, '_x': 43133}                                                                                             
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.connection]: >> Send data
  (Data=e3435f706476000100060101455f7077547909425f78317da8, FrameType=03)                                              
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.connection]: Received data
  (Data=040001a4e1435f7064929c010601020210[redacted-srp-exchange], FrameType=04)                                       
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.protocol]: Received frame FrameType.PS_Next:
  [redacted-srp-bytes]                                                                                                 
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.protocol]: Process incoming auth frame (FrameType.PS_Next):
  {'_pd': [redacted-srp-bytes]}                                                                                        
  2026-03-22 HH:MM:SS DEBUG [pyatv.protocols.companion.auth]: Got pub key and salt (PubKey=[redacted], Salt=[redacted])
  Enter PIN on screen:                                                                                                 
  [No PIN appeared on Apple TV screen.]

How to reproduce the bug?

  1. Install pyatv 0.17.0:
    pip3 install pyatv==0.17.0
  2. Confirm the Apple TV has only Companion, AirPlay and RAOP services (no MRP) via:
    atvremote scan
  3. With the Apple TV awake on the home screen, initiate Companion pairing:
    atvremote --protocol companion --address 192.168.x.x --id --debug pair
  4. Observe that:
    - The TCP connection to port 49153 succeeds
    - The SRP handshake completes (pub key and salt exchanged, FrameType.PS_Next received)
    - Enter PIN on screen: is printed
    - No PIN is shown. Connection eventually drops with Connection lost to remote device: None

What is expected behavior?

Expected

A 4-digit PIN should appear on the Apple TV screen.

Actual

No PIN is shown. Connection times out.

Operating System

Mac OS and Raspberry pi OS

Python

3.9

pyatv

0.17.0

Device

AppleTV 14,1

Additional context

  • getState() via atvscript works (returns deviceState, mediaType, etc.) — the device is reachable
  • The device has no MRP service (only Companion, AirPlay, RAOP)
  • Companion credentials are None (never successfully paired)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions