[SOLVED] Deutsche Telekom Call & Surf / Business DSL (tel.t-online.de) SIP Trunk – Outbound calls fail with “target number blocked” announcement / 603 Decline
Environment: FreePBX 17 / Asterisk 22, Debian 12, PJSIP trunk against tel.t-online.de (Deutsche Telekom’s residential/SMB “Call & Surf” telephony platform bundled with DSL contracts — not the separate business-grade “DeutschlandLAN SIP-Trunk” product)
Symptom
- Inbound calls work perfectly (including audio)
- Outbound calls: INVITE → Trying → Ringing → Session Progress → Telekom plays an announcement (“target number is blocked, connection not possible”) → call ends with SIP 603 Decline (HANGUPCAUSE=21 in Asterisk log)
- Trunk registration was always successful (pjsip show registrations → Registered)
- A parallel 3CX installation using the identical account credentials placed outbound calls without any issue
Things that were wrong but were NOT the root cause (worth checking too)
Before finding the actual fix, we found and corrected several other genuine misconfigurations. If you have similar symptoms, check these first:
- Registration pointed at 127.0.0.1 instead of tel.t-online.de (copy-paste error during setup)
- Wrong destination number format: Telekom Call & Surf expects the dialed number in national format with leading 0 (0XXXXXXXXXX), not international format (49XXXXXXXXXX). Adjust the Outbound Route dial pattern to strip a +49/49 prefix and prepend 0.
- Wrong SIP bind port due to a typo in Asterisk SIP Settings (UDP port accidentally set to 5061 instead of 5060)
- Transport TCP vs UDP: both work, this was not the deciding factor in the end
Root Cause
After fixing everything above, calls still got 603-Declined — the outgoing SIP requests were otherwise identical (format, auth, headers) to the working 3CX instance, except for one structural difference:
The trunk had a hard-coded Outbound Proxy (sip:tel.t-online.de) and a hard-coded SIP Server Port (5060) set, both on the endpoint and the registration object.
tel.t-online.de resolves to multiple different Telekom server IPs. When Asterisk builds the outbound INVITE target itself using a fixed outbound proxy/port, it can end up targeting a different server than the one it originally registered with. Telekom’s platform does not accept this and declines the call with a 603 after playing the announcement.
The Fix
In the trunk’s PJSIP settings (FreePBX GUI):
- General → SIP Server Port: leave completely empty (do NOT enter 5060)
- Advanced → Outbound Proxy: leave completely empty
This forces Asterisk to use the dynamically learned Contact from the registration response for outbound calls — guaranteeing the same server IP it registered with — instead of constructing its own (potentially different) target URI.
Verify in /etc/asterisk/pjsip.endpoint.conf / pjsip.registration.conf:
; Before (broken):
outbound_proxy=sip:tel.t-online.de
server_uri=sip:tel.t-online.de:5060
client_uri=sip:[email protected]:5060
; After (working):
; outbound_proxy removed entirely
server_uri=sip:tel.t-online.de
client_uri=sip:[email protected]
Then fwconsole restart and test.
Conclusion
If you have multiple DIDs each with their own trunk/registration (typical for this Telekom product), apply this fix to every single trunk.
Full anonymized config attached below for reference.
Anonymisierte vollständige Konfiguration (Anhang / Appendix)
/etc/asterisk/pjsip.endpoint.conf (nur die Telekom-Trunks):
[0XXXXXXXX1]
type=endpoint
transport=0.0.0.0-udp
context=from-pstn
disallow=all
allow=ulaw,alaw,gsm,g726,g722,h264,mpeg4
aors=0XXXXXXXX1
send_connected_line=no
rtp_keepalive=0
language=de_DE
outbound_auth=0XXXXXXXX1
from_domain=tel.t-online.de
- A parallel 3CX installation using the identical account credentials placed outbound calls without any issue
Things that were wrong but were NOT the root cause (worth checking too)
Before finding the actual fix, we found and corrected several other genuine misconfigurations. If you have similar symptoms, check these first:
- Registration pointed at 127.0.0.1 instead of tel.t-online.de (copy-paste error during setup)
- Wrong destination number format: Telekom Call & Surf expects the dialed number in national format with leading 0 (0XXXXXXXXXX), not international format (49XXXXXXXXXX). Adjust the Outbound Route dial pattern to strip a +49/49 prefix and prepend 0.
- Wrong SIP bind port due to a typo in Asterisk SIP Settings (UDP port accidentally set to 5061 instead of 5060)
- Transport TCP vs UDP: both work, this was not the deciding factor in the end
Root Cause
After fixing everything above, calls still got 603-Declined — the outgoing SIP requests were otherwise identical (format, auth, headers) to the working 3CX instance, except for one structural difference:
The trunk had a hard-coded Outbound Proxy (sip:tel.t-online.de) and a hard-coded SIP Server Port (5060) set, both on the endpoint and the registration object.
tel.t-online.de resolves to multiple different Telekom server IPs. When Asterisk builds the outbound INVITE target itself using a fixed outbound proxy/port, it can end up targeting a different server than the one it originally registered with. Telekom’s platform does not accept this and declines the call with a 603 after playing the announcement.
The Fix
In the trunk’s PJSIP settings (FreePBX GUI):
- General → SIP Server Port: leave completely empty (do NOT enter 5060)
- Advanced → Outbound Proxy: leave completely empty
This forces Asterisk to use the dynamically learned Contact from the registration response for outbound calls — guaranteeing the same server IP it registered with — instead of constructing its own (potentially different) target URI.
Verify in /etc/asterisk/pjsip.endpoint.conf / pjsip.registration.conf:
; Before (broken):
outbound_proxy=sip:tel.t-online.de
server_uri=sip:tel.t-online.de:5060
client_uri=sip:[email protected]:5060
; After (working):
; outbound_proxy removed entirely
server_uri=sip:tel.t-online.de
client_uri=sip:[email protected]
Then fwconsole restart and test.
Conclusion
If you have multiple DIDs each with their own trunk/registration (typical for this Telekom product), apply this fix to every single trunk.
Full anonymized config attached below for reference.
Anonymisierte vollständige Konfiguration (Anhang / Appendix)
/etc/asterisk/pjsip.endpoint.conf (nur die Telekom-Trunks):
[0XXXXXXXX1]
type=endpoint
transport=0.0.0.0-udp
context=from-pstn
disallow=all
allow=ulaw,alaw,gsm,g726,g722,h264,mpeg4
aors=0XXXXXXXX1
send_connected_line=no
rtp_keepalive=0
language=de_DE
outbound_auth=0XXXXXXXX1
from_domain=tel.t-online.de
from_user=0XXXXXXXX1
contact_user=0XXXXXXXX1
user_eq_phone=no
t38_udptl=no
t38_udptl_ec=none
fax_detect=no
trust_id_inbound=no
t38_udptl_nat=no
inband_progress=yes
direct_media=no
rtp_symmetric=yes
dtmf_mode=auto
[0XXXXXXXX2]
type=endpoint
transport=0.0.0.0-udp
context=from-pstn
disallow=all
allow=ulaw,alaw,gsm,g726,g722,h264,mpeg4
aors=0XXXXXXXX2
send_connected_line=no
rtp_keepalive=0
language=de_DE
outbound_auth=0XXXXXXXX2
from_domain=tel.t-online.de
from_user=0XXXXXXXX2
contact_user=0XXXXXXXX2
user_eq_phone=no
t38_udptl=no
t38_udptl_ec=none
fax_detect=no
trust_id_inbound=no
t38_udptl_nat=no
direct_media=no
rtp_symmetric=yes
dtmf_mode=auto
; — Trunks 0XXXXXXXX3, 0XXXXXXXX4, 0XXXXXXXX5 identisch aufgebaut —
/etc/asterisk/pjsip.registration.conf (nur die Telekom-Trunks):
[0XXXXXXXX1]
type=registration
transport=0.0.0.0-udp
outbound_auth=0XXXXXXXX1
retry_interval=60
fatal_retry_interval=300
forbidden_retry_interval=300
max_retries=10
expiration=480
auth_rejection_permanent=no
line=yes
endpoint=0XXXXXXXX1
contact_user=0XXXXXXXX1
server_uri=sip:tel.t-online.de
client_uri=sip:[email protected]
[0XXXXXXXX2]
type=registration
transport=0.0.0.0-udp
outbound_auth=0XXXXXXXX2
retry_interval=60
fatal_retry_interval=30
forbidden_retry_interval=30
max_retries=10000
expiration=3600
auth_rejection_permanent=no
line=yes
endpoint=0XXXXXXXX2
contact_user=0XXXXXXXX2
server_uri=sip:tel.t-online.de
client_uri=sip:[email protected]
; — Trunks 0XXXXXXXX3, 0XXXXXXXX4, 0XXXXXXXX5 identisch aufgebaut —
Wichtig: Bei keinem der Einträge darf mehr eine outbound_proxy=-Zeile stehen, und bei server_uri/client_uri darf kein Port (:5060) angehängt sein.
aors=0XXXXXXXX2
send_connected_line=no
rtp_keepalive=0
language=de_DE
dtmf_mode=auto
; — Trunks 0XXXXXXXX3, 0XXXXXXXX4, 0XXXXXXXX5 identisch aufgebaut —