There are two reasons why my code wasn't working. 1) My source(Italy mosaic) is in EPSG:4326 and the default OpenLayers projection is EPSG:900913 (or as known as EPSG:3857). Because of this mismatch either I had to get the Italy mosaic (my source) in EPSG:900913 or get it in EPSG:4326 but reproject it to EPSG:900913 to be able to see it on the screen. For now, I solved the problem by getting the Italy mosaic in EPSG:900913. 2) I had to add 'EPSG:900913: ' to my matrixIds[z] = z; value. Without this addition, the link goes to tile columns and rows that don't exist; here is how the request is seen from Fiddler : http://localhost:8081/geoserver/gwc/service/wmts?layer=nurc%3Amosaic&style=&tilematrixset=EPSG%3A900913&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&**TileMatrix=9&TileCol=280&TileRow=193** and on the browser [![matrixId[z] without addition of 'EPSG 900913: '[1]][1] And here how the code is seen when we write matrixIds[z] ='EPSG:900913:' + z; instead matrixIds[z] = z; http://localhost:8081/geoserver/gwc/service/wmts?layer=nurc%3Amosaic&style=&tilematrixset=EPSG%3A900913&Service=WMTS&Request=GetTile&Version=1.0.0&Format=image%2Fpng&TileMatrix=EPSG%3A900913%3A8&TileCol=141&TileRow=97 and on the browser [![with addition of 'EPSG 900913: '][2]][2] So here is my code: var projection = ol.proj.get('EPSG:900913'); var projectionExtent = projection.getExtent(); var size = ol.extent.getWidth(projectionExtent) / 256; var resolutions = new Array(14); var matrixIds = new Array(14); for (var z = 0; z < 14; ++z) { // generate resolutions and matrixIds arrays for this WMTS resolutions[z] = size / Math.pow(2, z); matrixIds[z] ='EPSG:900913:' + z; } var map = new ol.Map({ layers: [ new ol.layer.Tile({ source: new ol.source.OSM(), opacity: 0.7 }), new ol.layer.Tile({ opacity: 0.7, source: new ol.source.WMTS({ url: 'http://localhost:8081/geoserver/gwc/service/wmts?', layer: 'nurc:mosaic', matrixSet: 'EPSG:900913', format: 'image/png', projection: projection, tileGrid: new ol.tilegrid.WMTS({ origin: ol.extent.getTopLeft(projectionExtent), resolutions: resolutions, matrixIds: matrixIds }), style: '', wrapX: true }) }) ], target: 'map', controls: ol.control.defaults({ attributionOptions: { collapsible: false } }), view: new ol.View({ center: ol.proj.fromLonLat([27, 35]), zoom: 5 }) }); [1]: https://i.sstatic.net/5bbUN.png [2]: https://i.sstatic.net/tWC1S.png