Asterisk T.38

Be aware: T.38 is not T.38, there are still a great many interoperability issues out there!

Version information

  • Asterisk 1.2 has no support for T.38.
  • Asterisk 1.4 supports only T.38 fax pass through; there is however a third party way using HylaFax and OPAL to send and receive fax through Asterisk 1.4. See also rejected patch 12931 that includes a T.38 gateway. Attractel offers a commercial T.38 gateway solution for Asterisk.
  • In Asterisk 1.6 also origination and termination features will be added (with gateway functionality still missing)
  • NEW: In 2009 Digium introduced the commercial "Fax for Asterisk" with T.38 support (free licence for 1 channel)
  • For Asterisk 1.8 exist T.38 Gateway patch
  • In Asterisk 10 is Asterisk T.38 Gateway integrated


Q: Does Asterisk support T.38 ATAs behind NAT with canreinvite=no ?

A: See below

Q: Can I terminate T.38 calls to PSTN with Asterisk T.38 passthrough(via Zaptel)?

A: yes,


Gafachi all versions no Gafachi specifically mentions T.38 on their website, more info all versions yes T.38-optimized SIP trunks with official Asterisk support. more info


HT496 yes SVN TRUNK 40000 HT496 yes yes example
HT496 yes SVN-branch-1.4-r53152Patton SN4960 T4 no yes* sometimes bad quality(ht496 unregister after fax is sent)
SPA2100 3.3.6 no Branch 1.2+patches Cisco AS5300 IOS 12.3 no yes example
Kapanga 2152b no SVN-branch-1.4-r47911 Kapanga 2152b no yes* *receiving kapanga crash
Kapanga 2156 yes SVN-branch-1.4-r53152Patton SN4960 T4 no yes
Patton SN4524 3.20yes Asterisk 1.4.1 Patton SN4524 3.20 yesyes
SPA2102 5.1.6 yes Asterisk 1.4.2 Patton SN4960 R4.1 no NO
SPA2102 5.1.1 yes Asterisk 1.4.2 Patton SN4960 R4.1 no yes
SPA2102 5.2.5 yes Asterisk 1.4.19 Gafachi * no yes
SPA2102 5.2.5 no Asterisk / astlinux Zoiper Softphone ver 2.* no yes Tested in own private LAN. For zoiper: canreinvite=no, for the spa2102: canreinvite=yes and in the spa2102 configuration,the FAX passthrough method must be ReINVITE - then it works both ways. Obviously t38pt_udptl=yes must be set in sip.conf as described in the sip.conf.sample file (or google it)
Zoiper 2.09 (linux) no Asterisk SPA2102 5.2.5 no yes
Micronet SP5002/S 113 yes Asterisk 1.4.3 CISCO IOS N/A yes yes
Grandstream HT502 yes Asterisk 1.4.3 Patton SN4960 4.1 yes yes
Grandstream HT502 yes Asterisk 1.4.4 Grandstream HT502 yes yes
Grandstream GXW4004 yes Asterisk 1.4.4 Grandstream HT502 yes yes
Gafachi UAS 110.05 yes Asterisk 1.4.6+ Grandstream HT287 (aka HT286 v3.0) no yes
Grandstream HT287 (aka HT286 v3.0) no Asterisk 1.4.6+ Gafachi UAS 110.05 yes yes
Grandstream HT503 Prg. yes Asterisk 1.4.17 Grandstream HT503 Prg. yes yes
Mediatrix 1102 v5.0.19.124 yes Asterisk 1.4.18 Mediatrix 1102 v5.0.19.124 yes yes Same behaviour for all of mediatrix products line

Installation Procedures for Asterisk 1.6 with T.38 termination & origination

Asterisk 1.6 includes the ability to send and receive faxes if you compile it after installing appropriate support. After running configure, run "make menuselect" and see if app_fax is available or crossed out. If it is crossed out, you have not installed the needed support (or have not installed it to Asterisk's satisfaction).

Install the DAHDI drivers as documented elsewhere, then:

Get the latest version of Spandsp 0.0.6 from:

The commands below were written for version Spandsp 0.0.6-pre18 and Debian operating systems. The same packages are available for other distros.

apt-get install libtiff4 libtiff4-dev libtiff-tools
tar -xzvf spandsp-0.0.6pre18.tgz
cd spandsp-0.0.6
./configure --prefix=/usr
make install

After this, proceed with a standard installation of Asterisk 1.6, then make sure that sip.conf contains:

t38pt_udptl = yes

This must be in the [general] section or it will not work. You can disable it on a per-device basis, but it cannot be enabled in the device sections (as of Asterisk 1.6rc6). ;

Sample receive context in extensions.conf:

exten => _X.,n,ReceiveFax(faxfilename)

Important note : you should wait several seconds between Answer() and ReceiveFAX() in order for the fax to send a tone that asterisk can pick up to switch to t.38.
Your dialplan would then look something like

exten => _X.,1,Answer()
exten => _X.,n,Wait(6)
exten => _X.,n,ReceiveFAX(faxfilename)

Installation Procedure for Asterisk 1.6 with a T.38 gateway (Teles VoipBox PRI)

The Teles VoipBox we use is equipped with firmware version 14.5k. We used asterisk from the 1.6.1 branch with revision 209515 (just after a buch of T.38 rework was committed). This version will probably be released as very soon.

The VoipBox was configured with the following T.38 related settings in route.cfg:

VoipCompression=g711a t38
; Fax options
; Max 9600 baud
; Enable Error Correction Mode
; UDP datarate management 2
; Redundancy UDPTL ECM

If you use multiple profiles, make sure these settings are in effect for all profiles FROM and TO your asterisk box.;
You can crank up the speed after a few initial tests, but YMMV.

Asterisk was set-up with the following sip and udptl configuration values (tele1 is the teles gateway):

  1. Account for the teles box
sip.conf teles1 type peer
sip.conf teles1 host
sip.conf teles1 context default
sip.conf teles1 deny
sip.conf teles1 permit
  1. Required for fax to work, teles box operates out of spec
sip.conf teles1 ignoresdpversion yes
  1. Settings for fax
sip.conf general t38pt_udptl yes,redundancy

udptl.conf general T38FaxUdpEC t38UDPRedundancy
udptl.conf general udptlstart 4500
udptl.conf genera udptlend 30000
udptl.conf general T38FaxMaxDatagram 400

We set up a context for outbound and one for each fax box for inbound calls (and a ODBC function for fax logging):

extensions.conf	fax_out		exten	_X!,1,Set(ORIGREMOTESTATIONID=${REMOTESTATIONID})
extensions.conf	fax_out		exten	_X!,n,Answer()
extensions.conf	fax_out		exten	_X!,n,Wait(2)
extensions.conf	fax_out		exten	_X!,n,SendFax(${TIFF})
extensions.conf	fax_out		exten	_X!,n,Hangup()
extensions.conf	fax_out		exten	h,1,GotoIf($["${FAXSTATUS}"=""]?setreason:nosetreason)
extensions.conf	fax_out		exten	h,n(setreason),Set(FAXSTATUS="${REASON}")
extensions.conf	fax_out		exten	h,n(nosetreason),NoOp(Tried to send fax to ${REMOTESTATIONID}, result ${FAXSTATUS})
extensions.conf	fax_out		exten	h,n,GotoIf($["${FAXSTATUS}"="SUCCESS"]?succ:fail)
extensions.conf	fax_out		exten	h,n(succ),Set(FAX_LOG_RESULT=${ODBC_FAX_LOG("${JOBID}", SENT, "${SENDER}", "${REMOTESTATIONID}", "${ORIGREMOTESTATIONID}", "${FAXPAGES}", "${FAXRESOLUTION}", "${FAXBITRATE}", "${FAXERROR}", "${ACCOUNT}", "${DATA}")})
extensions.conf	fax_out		exten	h,n,Goto(cont)
extensions.conf	fax_out		exten	h,n(cont),NoOp(Fax sending done)
extensions.conf	fax_out		exten	failed,1,NoOp(Failed: Sending fax to ${REMOTESTATIONID}, reason ${REASON})

extensions.conf	default		exten	3987,1,Answer()
extensions.conf	default		exten	3987,n,Wait(2)
extensions.conf	default		exten	3987,n,Set(TIFF=/var/spool/fax_in/fax_${STRFTIME(,,%Y%m%d-%H%M)}_${RAND(1)}.tiff)
extensions.conf	default		exten	3987,n,ReceiveFAX(${TIFF})
extensions.conf	default		exten	3987,n,GotoIf(${FAXSTATUS}="SUCCESS"?succ:fail)
extensions.conf	default		exten	3987,n(succ),Set(FAX_LOG_RESULT=${ODBC_FAX_LOG(-1, RECEIVED, 3987, "${REMOTESTATIONID}", "${CALLERID(num)}", "${FAXPAGES}", "${FAXRESOLUTION}", "${FAXBITRATE}", "${FAXERROR}", "3987", "testBox")})
extensions.conf	default		exten	3987,n,Goto(cont)
extensions.conf	default		exten	3987,n(fail),Set(FAX_LOG_RESULT=${ODBC_FAX_LOG(-1, RECEIVED_FAILED, 3987, "${REMOTESTATIONID}", "${CALLERID(num)}", "${FAXPAGES}", "${FAXRESOLUTION}", "${FAXBITRATE}", "${FAXERROR}", "3987", "testBox")})
extensions.conf	default		exten	3987,n(cont),NoOp()
extensions.conf	default		exten	3987,n,System( -f ${TIFF} -s "Fax box testBox <3987> Fax from ${REMOTESTATIONID}" -e [email protected])
extensions.conf	default		exten	3987,n,Hangup()

func_odbc.conf		FAX_LOG		dsn	asterisk
func_odbc.conf		FAX_LOG		read	insert into fax_log ("time", jobid, event, localid, remoteid, dialledremoteid, pages, resolution, bitrate, errorstring, data1, data2) values (EXTRACT(EPOCH FROM now()), regexp_replace('${SQL_ESC(${ARG1})}','^[^0-9]*','0','g')::int, '${SQL_ESC(${ARG2})}', '${SQL_ESC(${ARG3})}', '${SQL_ESC(${ARG4})}', '${SQL_ESC(${ARG5})}', regexp_replace('${SQL_ESC(${ARG6})}','^[^0-9]*','0','g')::int, '${SQL_ESC(${ARG7})}', '${SQL_ESC(${ARG8})}', '${SQL_ESC(${ARG9})}', '${SQL_ESC(${ARG10})}','${SQL_ESC(${ARG11})}')

An outbound fax can then be sent by creating a call file like:

Channel: [email protected]
CallerID: T38 SendFax
WaitTime: 180
MaxRetries: 0
RetryTime: 300
Archive: false
Context: fax_out
Extension: 00430000000
Priority: 1
SetVar: SENDER=Yourname <>
SetVar: T38CALL=1
SetVar: TIFF=/tmp/fax_out_8db15599-c9d7-4b06-94a7-aeddbb1112e0.tiff
SetVar: ACCOUNT=3987
SetVar: REMOTESTATIONID=00430000000

Installation Procedures for Asterisk 1.4 with T.38

Installation Note: By default, Asterisk doesn't set many of the T.38 settings that may be required to interface with third party SIP trunks. You must make these changes within the chan_sip.c file before doing a make install. The T.38 configuration settings is located in chan_sip.c and can be edited with VI or your favorite text editor. The setting is modified with the line that reads as follows:

/*!< This is default: NO MMR and JBIG trancoding, NO fill bit removal, transferredTCF TCF, UDP FEC, Version 0 and 9600 max fax rate */
static int global_t38_capability = T38FAX_VERSION_0 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600;

To make changes to the T38 configuration, simply add in the changes as described in the sections above that line. For example, if you need T38FAX_VERSION_1 simply edit the file and change the 0 to 1. If you can support 12000 and 14400, simply add it to the end of the line. An example configuration with T38 verison 1 and adding 12000 and 14400 follows:

static int global_t38_capability = T38FAX_VERSION_1 | T38FAX_RATE_2400 | T38FAX_RATE_4800 | T38FAX_RATE_7200 | T38FAX_RATE_9600 | T38FAX_RATE_12000 | T38FAX_RATE_14400;


cd /usr/src
svn checkout asterisk-1.4
(or for trunk:
svn checkout asterisk-trunk
cd asterisk-1.4 (cd asterisk-trunk)
./configure;make;make install
asterisk -vvvdc



t38pt_udptl = yes

t38pt_udptl = yes

or take a look at a NATted variant:

t38pt_udptl = yes

t38pt_udptl = yes


exten => 200,1,Dial(SIP/${EXTEN}|300)
exten => 201,1,Dial(SIP/${EXTEN}|300)

Now dial 201 from 200.

Additional Troubleshooting

Depending on your fax device (such as the Linksys 3102) you may have to edit the udptl.conf file. The error correction type that is sent is usually the culprit of many problems with ATAs and T.38 providers.

Also, try using:


... in the general section of the sip.conf and under the VoIP provider account as well as the fax account.

Also, crank down the speed of the fax machine to the slowest speed possible. Some ATAs work better like this.

-For the SPA2102 (probably the same for 3102) and Asterisk 1.4 make sure that in the SPA web admin utility, the FAX Passthrough method = ReINVITE. In asterisk's sip.conf make sure canreinvite=yes.

-Zoiper softphone supports T.38 faxing only, which is a great way to test if T38 is actually working (and that you are not fooled by a sneaky G711 fallback). For Zoiper (version 2.*) configuration in sip.conf, it is important that canreinvite=no.

-If you get this Warning: Unsupported SDP media type in offer: image XXXX udptl t38. It means the originator is sending a T.38 fax but you do not have t38pt_udptl enabled in sip.conf

-If your sending fax machine says something like "No fax machine answering" then you may need to increase the time that asterisk has to detect a fax by increasing the wait between Answer and ReceiveFax().

Installation Procedures for Asterisk T.38 Over FreePBX 2.4

  1. Setup /etc/asterisk/udptl.conf manually
  2. add "t38pt_udptl=yes" to /etc/asterisk/sip_general_custom.conf

Step 2 basically tells asterisk that ALL of your SIP peers are T.38 capable (which is probably not true, but not really harmful either)

HowTo debug & send bugreports

Please read

1) Prepare test environment (reduce the ammount of unrelated traffic on the server);

2) Make sure your logger.conf has the following line:

console => notice,warning,error,debug

3) restart Asterik.

4) Enable SIP transaction logging with the following CLI commands:

set debug 4 (latest trunk "core debug 4")
set verbose 4 (latest trunk "core verbose 4")
sip debug

5) Save complete console log to file

6) Create bugreport at

7) Attach saved file to the bug.

See also

Created by: cervajs, Last modification: Tue 30 of Jun, 2015 (22:55 UTC) by dazza321
Please update this page with new information, just login and click on the "Edit" or "Discussion" tab. Get a free login here: Register Thanks! - Find us on Google+