livekit/livekit · warning

DependencyDescriptorReader: too many templates

Error message

DependencyDescriptorReader: too many templates

What it means

ErrDDReaderTooManyTemplates is returned by readTemplateLayers when a structure declares MaxTemplates templates, exceeding the AV1 spec limit. It is a guard against unbounded allocation and hostile descriptors.

Source

Thrown at pkg/sfu/rtpextension/dependencydescriptor/dependencydescriptorreader.go:24

//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dependencydescriptor

import (
	"errors"
)

var (
	ErrDDReaderNoStructure              = errors.New("DependencyDescriptorReader: Structure is nil")
	ErrDDReaderTemplateWithoutStructure = errors.New("DependencyDescriptorReader: has templateDependencyStructurePresentFlag but AttachedStructure is nil")
	ErrDDReaderTooManyTemplates         = errors.New("DependencyDescriptorReader: too many templates")
	ErrDDReaderTooManyTemporalLayers    = errors.New("DependencyDescriptorReader: too many temporal layers")
	ErrDDReaderTooManySpatialLayers     = errors.New("DependencyDescriptorReader: too many spatial layers")
	ErrDDReaderInvalidTemplateIndex     = errors.New("DependencyDescriptorReader: invalid template index")
	ErrDDReaderInvalidSpatialLayer      = errors.New("DependencyDescriptorReader: invalid spatial layer, should be less than the number of resolutions")
	ErrDDReaderNumDTIMismatch           = errors.New("DependencyDescriptorReader: decode target indications length mismatch with structure num decode targets")
	ErrDDReaderNumChainDiffsMismatch    = errors.New("DependencyDescriptorReader: chain diffs length mismatch with structure num chains")
)

type DependencyDescriptorReader struct {
	// Output.
	descriptor *DependencyDescriptor

	// Values that are needed while reading the descriptor, but can be discarded
	// when reading is complete.
	buffer                         *BitStreamReader
	frameDependencyTemplateId      int
	activeDecodeTargetsPresentFlag bool
	customDtisFlag                 bool

View on GitHub (pinned to ee45c3f0b1)

Solutions

  1. Drop the packet / invalidate the descriptor when the limit is hit (spec-conformant behavior)
  2. Sanity-check the descriptor payload size before parsing to reject oversized counts early
  3. Update encoder/library versions if a legit encoder is exceeding the limit

Example fix

// before
for {
    templates = append(templates, t)
}
// after
for {
    if len(templates) == MaxTemplates {
        return ErrDDReaderTooManyTemplates // bounded, spec-compliant
    }
    templates = append(templates, t)
}
Defensive patterns

Strategy: validation

Validate before calling

if payloadLen > maxReasonableDescriptorSize {
    return errors.New("descriptor payload too large")
}

Try / catch

err := reader.ReadTemplateLayers()
if errors.Is(err, dd.ErrDDReaderTooManyTemplates) {
    reader.Buffer().Invalidate() // drop packet
}

Prevention

When it happens

Trigger: readTemplateLayers loop hits len(templates) == MaxTemplates while parsing templateDependencyStructure (line 218); caused by a corrupt template count in the payload.

Common situations: Malformed/attacker-crafted dependency descriptor payloads; interoperability with non-conformant encoders emitting more templates than allowed.

Related errors


AI-assisted analysis of livekit/livekit@ee45c3f0b1 (2026-09-02). Data as JSON: /api/errors/ffdc274910eb4cce. Report an issue: GitHub.